Perl:不要打印任何重复的行

时间:2017-06-05 20:44:49

标签: perl

什么是Perl单行程序才能打印那些只出现过一次的行(也就是说,如果它出现不止一次就不打印 - 真正独特的行)?

例如,如果我有一个包含重复行的文件:

line1
line2
line2
line3
line1
line4
line5

输出应为:

line3
line4
line5

我可以perl -ne 'print if $a{$_}++' file只查看重复的行...

line2
line1

我可以将if替换为其反义词unless,并且只能查看文件中每行的一次出现...

perl -ne 'print unless $a{$_}++' file
line1
line2
line3
line4
line5

我假设我必须在整个文件中插入并使用每行的单\n分隔符处理它,可能是哈希?只是不知道该怎么做。

4 个答案:

答案 0 :(得分:4)

另一种方法:

perl -e'@a=<>; $d{$_}++ for @a; print grep {$d{$_}<2} @a' file

答案 1 :(得分:2)

您只有在读完所有行后才知道某条线是否是唯一的,所以在到达文件末尾之前无法开始打印!

# Varying order

perl -nle'++$lines{$_}; END { print for grep $lines{$_}==1, keys %lines; }' file

# Sorted

perl -nle'++$lines{$_}; END { print for sort grep $lines{$_}==1, keys %lines; }' file

# Original order

perl -nle'
   if ( my $orig_line_num = $line_nums_by_line{$_} ) {
      $lines_by_line_num[$orig_line_num] = undef;
   } else {
      $lines_by_line_num[$.] = $_;
      $line_nums_by_line{$_} = $.;
   }

   END { print for grep defined, @lines_by_line_num; }
' file

答案 2 :(得分:2)

如上所述,要以这种方式过滤文件并按顺序保留行,您需要读取文件两次或在阅读时存储行号信息

这个单线程似乎是最好的选择

perl -e '@a = @ARGV; ++$c{$_} while <>; @ARGV = @a; $c{$_} == 1 and print while <>;'  myfile.txt

输出

line3
line4
line5

这是一个稍短的替代方案,但它使用两倍的内存来存储文件数据

perl -e '@l = <>; ++$c{$_} for @l; $c{$_} == 1 and print for @l;' myfile.txt

答案 3 :(得分:1)

虽然它是一个Unix解决方案,但它应该可以工作:

{{1}}

line3中
4号线
第5行

其中file1具有:
LINE1
2号线
2号线
3号线
一号线
4号线
LINE5

uniq命令的-u选项仅列出非重复条目,uniq用于排序输出