刪除兩個命令產生的輸出共有的行

刪除兩個命令產生的輸出共有的行

比如說,我有兩個回傳一些文字的命令。例如:

$ ./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]++'

這不需要時間進行排序,但需要記住所看到的行。因此,對於大量輸入sortuniq可能會更好......

答案4

我建議利用它sed來解析文字並刪除重複的行。所以第一個指令保留重複行 sed '$!N; /^\(.*\)\n\1$/!P; D'

第二條指令將刪除重複項 sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'

相關內容