您可以尝试另一种选择,通过两次读取输入文件来保持顺序:
awk 'NR==FNR{A[$1]=NR; next} A[$1]!=FNR{print>f; next}1' f=dups file file
输出:
bar bn
fjk ff
foo jj
xxx tt
kkk hh
重复:
$ cat dups
foo j
bar bn
bar b
bar bn
bar bn
kkk hh
@Sudo_O @WilliamPursell @user2018441。Sudo_O 感谢您的性能测试。我试图在我的系统上重现它们,但它没有tac
可用,所以我用 Kent 的版本和我的版本进行了测试,但我无法在我的系统上重现这些差异。
更新:我使用 Sudo_O 的版本cat
而不是tac
. 尽管在一个系统上,输出到 /dev/null 之间和输出到 /dev/nulltac
之间有 0.2 秒的差异(参见这篇文章的底部)tac
cat
我有:
Sudo_O
$ time cat <(seq 1 1000000) | awk 'a[$1]++{print $0 > "/dev/null";next}{print $0 > "/dev/null"}'
real 0m1.491s
user 0m1.307s
sys 0m0.415s
kent
$ time awk '$1 in a{print a[$1]>"/dev/null"}{a[$1]=$0}END{for(x in a)print a[x]}' <(seq 1 1000000) > /dev/null
real 0m1.238s
user 0m1.421s
sys 0m0.038s
scrutinizer
$ time awk 'NR==FNR{A[$1]=NR; next} A[$1]!=FNR{print>f; next}1' f=/dev/null <(seq 1 1000000) <(seq 1 1000000) > /dev/null
real 0m1.422s
user 0m1.778s
sys 0m0.078s
--
使用文件而不是seq
我得到的文件时:
Sudo_O
$ time cat <infile | awk 'a[$1]++{print $0 > "/dev/null";next}{print $0 > "/dev/null"}'
real 0m1.519s
user 0m1.148s
sys 0m0.372s
kent
$ time awk '$1 in a{print a[$1]>"/dev/null"}{a[$1]=$0}END{for(x in a)print a[x]}' <infile > /dev/null
real 0m1.267s
user 0m1.227s
sys 0m0.037s
scrutinizer
$ time awk 'NR==FNR{A[$1]=NR; next} A[$1]!=FNR{print>f; next}1' f=/dev/null <infile <infile > /dev/null
real 0m0.737s
user 0m0.707s
sys 0m0.025s
可能是由于缓存效果,这也将出现在较大的文件中。创建 infile 需要:
$ time seq 1 1000000 > infile
real 0m0.224s
user 0m0.213s
sys 0m0.010s
在不同的系统上测试:
$ time cat <(seq 1 1000000) > /dev/null
real 0m0.764s
user 0m0.719s
sys 0m0.031s
$ time tac <(seq 1 1000000) > /dev/null
real 0m1.011s
user 0m0.820s
sys 0m0.082s