新手请教 一个文件排序问题



QUOTE:
原帖由 churchmice 于 2008-4-10 09:48 发表

niubility
只听说过awk,具体没有怎么用过
那时认为perl兼容了awk和sed,所以对这两个工具就直接无视了

Perl 的确可以实现像awk,sed,grep之类的Unix工具的功能,不过各有各的优点了,看你怎么用了。
小弟新手!

想请教一下churchmice的代码中的几个问题:
#!/usr/bin/perl
use strict;
use warnings;
my $text = shift || "1.txt";
open my $file,"<",$text or die "Fail to open $text $!";
my %hash;
while(<$file>){
     my ($key,$value) = split /\s+/;
     $hash{$key} = $value;
     }
open my $out,">","2.txt" or die "Fail to create 2.txt $!";
print $out "$_ $hash{$_}\n" foreach ( sort { $hash{$a} <=> $hash{$b} }keys %hash);

(1):my $text = shift || "1.txt";这段代码中的shift起什么作用呢!
(2):foreach ( sort { $hash{$a} <=> $hash{$b} }keys %hash);最后以行的代码中<=>又是什么意思呢?

非常感谢!
(1):my $text = shift || "1.txt";这段代码中的shift起什么作用呢!
这个我也不理解作者的意思.

(2):foreach ( sort { $hash{$a} <=> $hash{$b} }keys %hash);最后以行的代码中<=>又是什么意思呢?
这个是比较$hash{$a}和$hash{$b} 数值的操作符,相等时候为0,如果$hash{$a}大为1,如果$hash{$b}为-1. 这个比较符在sort函数中非常有用。

(我也是新手,如果解析有错,请大牛们指点。)
谢谢,可是我还没明白。
sort { $hash{$a} <=> $hash{$b} }keys %hash

$a,$b都是在那儿定义的,跟%hash德关系是什么,正常我们可以这样使用:sort keys %hash.
可是如果在sort和keys中间插入一个比较的结果(-1,0,1),那又是什么意思呢?


QUOTE:
原帖由 andy820303 于 2008-4-10 16:15 发表
谢谢,可是我还没明白。
sort { $hash{$a}  $hash{$b} }keys %hash

$a,$b都是在那儿定义的,跟%hash德关系是什么,正常我们可以这样使用:sort keys %hash.
可是如果在sort和keys中间插入一个比较的结果( ...

这个只是我的一些个人习惯
1.my $text = shift || "1.txt";
这一句的作用就是默认的输入文件是1.txt
当然你也可以通过命令行传递一个参数,改写默认的输入文件
这里shift的默认对象是@ARGV
相当于
my $text = shift @ARGV || "1.txt"
意思应该很明显了吧
就是说取命令行的第一个参数做为$text的值,也就是my $text = $ARGV[0];
如果没有命令行参数则执行
my $text = "1.txt"
这样仅仅是个人习惯,使得程序更加灵活
2.排序问题有两个默认变量$a和$B,这个是predefined value

QUOTE:
perldoc perlvar
       $a
       $b      Special package variables when using sort(), see "sort" in
               perlfunc.  Because of this specialness $a and $b don’t need to
               be declared (using local(), use vars, or our()) even when using
               the strict vars pragma.  Don’t lexicalize them with "my $a" or
               "my $b" if you want to be able to use them in the sort() com-
               parison block or function.

关于<=>等排序的内容具体可以参见小骆驼书(learning perl),里面应该说的很清楚了
简单的说
$a<=>$b 是按数字升序的方式排(默认的排列方法)
$b<=>$a 是按数字降序的方式排
比如说下面的代码

[Copy to clipboard] [ - ]
CODE:
my @sorted = sort @data;  #升序排
my @sorted = sort { $a<=>$b} @data;#同上
my @sorted = sort {$b<=>$a} @data;#降序排
my @sorted = reserve sort @data;#同上

如果这个清楚的话那么那段代码也很好理解了

[Copy to clipboard] [ - ]
CODE:
foreach( sort {$hash{$a}<=>$hash{$b}} keys %hash)

在这里$a,$b是%hash中的key
排列的比较原则是
$hash{$a}<=>$hash{$b}
也就是说%hash的值相比较
希望我已经解释清楚了
谢谢.非常清楚,看不懂就只能怪自己了!

怪自己看书看的太不仔细,2个晚上就把小骆驼书看完了,结果什么也没记下来,跟没看差不多!真是丢人啊!

再次感谢!


QUOTE:
原帖由 andy820303 于 2008-4-10 22:21 发表
谢谢.非常清楚,看不懂就只能怪自己了!

怪自己看书看的太不仔细,2个晚上就把小骆驼书看完了,结果什么也没记下来,跟没看差不多!真是丢人啊!

再次感谢!

书读百遍
其义自现
请教,如果1.txt中出现了value相同的值。譬如:
大 11111
小 11111
三 11111
哪么如何在输出的txt中这样显示
11111 大小三  ????
我这样写的不行:
#!/usr/bin/perl
use strict;
use warnings;
open my $file,"<new word.txt"or die "Fail to open text $!";
my %hash;
my @array;
while(<$file>){
        my ($key,$value) = split/\s+/;
        $hash{$key}=$value;
}
open my $out,">3.bin" or die "Fail to creat2.txt $!";
sub by_num
{
        if($hash{$a}<=>$hash{$b})
        {
                push @array,$hash{$_};
                push @array,$_;
        }
        else{
        push@array,$_;
        }
}
foreach(my@result=sort by_num keys %hash)
{
        print $out "@array\n";
}


QUOTE:
原帖由 churchmice 于 2008-4-10 09:28 发表
先读入一个hash中,然后根据value排序

#!/usr/bin/perl
use strict;
use warnings;
my $text = shift || "1.txt";
open my $file,"","2.txt" or die "Fail to create 2.txt $!";
print $out "$_ $hash{$ ...

偶认为这个比较正解。。。
就是在上面这个的基础上修改哈 ,不知道怎么修改。。。。。