集合演算っぽくファイルの足し算と引き算をする
実は僕はソフトウェアエンジニアなのです。というわけで、(たしか)初の技術ネタ。
Unixファイルシステム上に、次のようなソート済みのfile1とfile2があるとします。
$ cat file1 a b d e $ cat file2 b c d f
それぞれのファイルを集合、各行を要素と見なして、Unixコマンドのみで演算をしてみる。
file1とfile2を単純に足し算(結合)する場合はこう。
$ cat file1 file2 a b d e b c d f
でも、これだと全然集合っぽくない。
和集合(file1∪file2)
file1とfile2の少なくとも一方に含まれる要素を重複なしでリストする。
$ cat file1 file2 | sort | uniq a b c d e f
こんな書き方もできる。
$ join -a1 -a2 file1 file2 a b c d e f
差集合(file1―file2)
file1に含まれるけど、file2には含まれない要素をリスト。
$ diff file1 file2 | awk '/^</{print $2}' a e
分かりづらいので、diffの出力だけを見てみる。
$ diff file1 file2 1d0 < a 2a2 > c 4c4 < e --- > f
'd'のセクションにリストされる要素は、file1にしか含まれないという意味なので、結果集合に含まれる。
'a'のセクションはfile2にのみ含まれるので、結果集合には含まれない。
'c'のセクションはfile1のほうの要素だけが結果集合に含まれる。
要は、行頭の文字が'<'の場合に、空白以降を出力すればよい。そのフィルターをawkでやっている。
積集合(file1∩file2)
file1とfile2の両方に含まれる要素をリスト。これは意外と楽チン。
$ join file1 file2 b d