比如说,我有两个返回一些文本的命令。例如:
$ ./c1
/usr/bin/foo
/usr/bin/bar
/usr/bin/baz
$ ./c2
/usr/bin/foo
/usr/bin/qux
/usr/bin/buzz
/usr/bin/bar
我想删除重复的行;即输出将是(顺序并不重要):
/usr/bin/baz
/usr/bin/qux
/usr/bin/buzz
我该怎么做呢?
答案1
一个相当简单的管道应该可以解决问题:
(./c1; ./c2) | sort -u
括号获取两者的标准输出./c1
并./c2
进入命令的标准输入sort
。该选项-u
仅打印每组匹配行中的 1 个。
感谢 John WH Smith 注意到了简化,感谢 Bakuriu 的见解。
答案2
与comm
来自GNU coreutils
:
$ comm -3 <(sort -u <(./c1)) <(sort -u <(./c2)) | tr -d '\t'
/usr/bin/baz
/usr/bin/buzz
/usr/bin/qux
从man comm
:
Compare sorted files FILE1 and FILE2 line by line.
With no options, produce three-column output. Column one contains
lines unique to FILE1, column two contains lines unique to FILE2, and
column three contains lines common to both files.
-1 suppress column 1 (lines unique to FILE1)
-2 suppress column 2 (lines unique to FILE2)
-3 suppress column 3 (lines that appear in both files)
答案3
awk-pipe 只让第一次出现的输入行通过:
( ./c1 ; ./c2 ) | awk '!u[$0]++'
这不需要时间进行排序,但需要记住所看到的行。因此,对于大量输入sort
,uniq
可能会更好......
答案4
我建议利用它sed
来解析文本并删除重复的行。所以第一个命令保留重复行
sed '$!N; /^\(.*\)\n\1$/!P; D'
第二条命令将删除重复项
sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'