2つのコマンドによって生成された出力に共通する行を削除する

2つのコマンドによって生成された出力に共通する行を削除する

たとえば、テキストを返す 2 つのコマンドがあるとします。たとえば、次のようになります。

$ ./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

から:commGNU 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'

2番目のコマンドは重複を削除します sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'

関連情報