25

这个 perl 单行如何显示 2 个文件共有的行?

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/'  file1 file2
4

2 回答 2

28

命令行选项将-n代码转换为等价于

while ($ARGV = shift @ARGV) {
  open ARGV, $ARGV;
  LINE: while (defined($_ = <ARGV>)) {
    $seen{$_} .= @ARGV;
    print $_ if $seen{$_} =~ /10$/;
  }
}

在读取第一个文件时,scalar @ARGV1. 对于每一行,1将附加到%seen条目中。

在读取第二个文件时,scalar @ARGV0. 因此,如果一行在文件 1 和文件 2 中,则条目将如下所示1110000(在文件 1 中是 3×,在文件 2 中是 4×)。

我们只想准确地输出公共线一次。当第一次在 file2 中看到公共行时,我们会这样做,$seen{$_}所以1110. 这表示为正则表达式/10$/:字符串10必须出现在末尾。

于 2013-07-09T16:05:32.947 回答
3

打开第一个文件时,@ARGV 会移动。在标量上下文中,它现在返回 1(因为它有一个成员,即第二个文件)。对于每一行,这个 1 被附加到散列 %seen。打开第二个文件时,@ARGV 再次移动,现在为空,因此在标量上下文中返回 0。/10$/表示“该行已在 file1 中看到,现在它已首次在 file2 中看到”。

于 2013-07-09T16:05:16.943 回答