【问题标题】:How can I get the name of the input file in a Perl one-liner?如何在 Perl 单行中获取输入文件的名称?
【发布时间】:2011-04-26 07:00:12
【问题描述】:

文件 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

文件 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 单行器从文件“monday.csv”中的第一列中的前三位是 227 或 226 的行中为我提供第二列中具有最高值的行:

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

这个 Perl 单行器在第一列中的所有 *day.csv 文件中的前 3 位数字为 227 或 226 的行中为我提供第二列中具有最高值的行:

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

我怎样才能重写这个单行以获得类似的输出

filename : "文件 'filename.csv' 中第一列前 3 位为 227 或 226 的行中第二列中具有最高值的行"

对于每个*day.csv 文件?

【问题讨论】:

    标签: perl command-line-arguments argv


    【解决方案1】:

    您可以使用$ARGV 作为当前文件名。如果您只对最大值感兴趣,则无需存储所有值然后对其进行排序;相反,只需存储每个文件的最大值。此外,您的正则表达式可能应该锚定到行首。

    # 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
    

    【讨论】:

      【解决方案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
      

      【讨论】:

      • 我没有看到重复值的问题。
      • 在第一列。但是我在第二列中看到了重复值的问题。原因是,它忘了提到,如果每个文件有一个以上的最高值,我想从最高值中获得文件中的最后一个值。
      • 但是我认为你的第二个单行中有很多错误。
      【解决方案3】:

      看来你可以使用$ARGV。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-03
        相关资源
        最近更新 更多