如何在Perl单行中获取输入文件的名称?

时间:2010-10-16 09:52:59

标签: perl command-line-arguments argv

cat monday.csv

  

223.22; 1256.4
  227.08; 1244.8
  228.08; 1244.7
  229.13; 1255.0
  227.89; 1243.2
  224.77; 1277.8

cat tuesday.csv

  

227.02; 1266.3
  227.09; 1234.9
  225.18; 1244.7
  224.13; 1255.3
  228.59; 1263.2
  224.70; 1247.6

这个Perl一行代表给出了第二列中最高值的行,其中第一列中的前3位数字是227或226来自文件“monday.csv”:

$ perl -F\; -ane '$hash{$_} = $F[1] if /22[78]/; END{ print and exit for sort{ $hash{$b} <=> $hash{$a} } keys %hash }' monday.csv

这个Perl单行为我提供了第二列中最高值的行,其中第一列中的前三个数字是227或226来自所有* day.csv文件:

$ perl -F\; -ane '$hash{$_} = $F[1] if /22[78]/; END{ print and exit for sort{ $hash{$b} <=> $hash{$a} } keys %hash }' *day.csv

我怎样才能重写这个单行来获得输出:

  

filename:“第一列中第一列中具有最高值的行,其中第一列中的前3位数字是227或226来自文件'filename.csv'”

每个*day.csv文件

4 个答案:

答案 0 :(得分:5)

您可以使用$ARGV作为当前文件名。如果您只对max感兴趣,则无需存储所有值,然后对它们进行排序;相反,只需存储每个文件的最大值。另外,你的正则表达式可能应该固定在行的开头。

# Line breaks added for display purposes.
perl -F\; -ane '
    $max{$ARGV} = $F[1] if /^22[78]/ and $F[1] > $max{$ARGV};
    END{ print "$_\t$max{$_}" for sort keys %max}
' *day.csv

或者,如果您想要存储最大值的整行:

perl -F\; -ane '
    ($max{$ARGV}{ln}, $max{$ARGV}{mx}) = ($_, $F[1])
        if /^22[78]/ and $F[1] > $max{$ARGV}{mx};
    END{ print "$_\t$max{$_}{ln}" for sort keys %max}
' *day.csv

答案 1 :(得分:2)

文件名包含在$ARGV变量中:

  

$ ARGV

     

包含从<>。

读取时当前文件的名称

然而,所提出的单行有一个问题;如果你有第一列的重复值怎么办?

更好的单线将是:

$ perl -F/;/ -MList::Util=max -lane 'push @{ $wanted{$ARGV} }, $F[1] if $F[0] =~ /22[78]/; } END { print "$ARGV : ", max(@{ $wanted{$_} }) for keys %wanted;' *.csv

基于评论:

$ perl -F/;/ -lane '$wanted{$ARGV} = \@F if $F[1] >= $wanted->{$ARGV}[1] && $F[0] =~ /22[78]/; } END { print "$_ : @$wanted{$_}" for keys %wanted;' *.csv

答案 2 :(得分:0)

似乎你可以使用$ ARGV。请参阅“current filename

答案 3 :(得分:0)

如果我想要整行,我可以这样做(根据FM的答案):

perl -F\; -ane '$max{$ARGV} = $_ if /^22[78]/ and $F[1] >= (split /;/, $max{$ARGV})[1];  END{ print "$_\t$max{$_}" for sort keys %max}' *day.csv

我找到了一个更短的解决方案 所有文件:

perl -F\; -anE '$max{$ARGV} = [@F] if /^22[78]/ and $F[1] >= $max{$ARGV}->[1];  END{ print "$_\t@{$max{$_}}" for sort keys %max}' *day.csv

一个文件:

perl -F\; -anE '$max = [@F] if /^22[78]/ and $F[1] >= $max->[1]; END{ print "@$max" }' monday.csv

或者如果可用空间不足

perl -F\; -anE'$m{$ARGV}=[@F]if/^22[78]/&&$F[1]>=$$m{$ARGV}[1]}print"$_\t@{$m{$_}}"for sort keys%m;{' *day.csv

perl -F\; -anE'$m=[@F]if/^22[78]/&&$F[1]>=$$m[1]}print"@$m";{' monday.csv

正如扎伊德透露的那样:为了在文件中重复出现最高值的情况下得到最高值的最后一行,我改变了“$ F [1]> $ max ...” - 部分为“$ F [1 ]> = $ max“。