什么是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
分隔符处理它,可能是哈希?只是不知道该怎么做。
答案 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用于排序输出