dullwhaleのメモ帳

何度も同じことを調べなくてよいように...

commコマンドを用いてファイルの行の差集合を得る

commコマンドを使え

commコマンドはdiffコマンドよりも賢くないが、CSVファイルの比較などにとても強い。 ユーザ一覧などを突合して棚卸しする際などに活躍する。

commコマンドに渡すファイルはあらかじめソートしておく必要がある。

# 引数で指定した左側のファイルにだけ存在する行を取得する
comm -23 left.txt right.txt
# 引数で指定した右側のファイルにだけ存在する行を取得する
comm -13 left.txt right.txt
# おまけ 積集合をとる
comm -12 left.txt right.txt

具体例と解説

次のような2つのファイルがあるとする。

left.txtファイル

B
C
E
G
I
J

right.txtファイル

A
B
D
E
F
G
H
J

ここで何もオプションを付けずにcommコマンドを実行すると、次の出力が得られる。

% comm left.txt right.txt
    A
        B
C
    D
        E
    F
        G
    H
I
        J

出力の読み方

  • 左の列にあるのが、左のファイルにしか存在しない行
  • 中央の列にあるのが、右のファイルにしか存在しない行
  • 右の列にあるのが、両方のファイルに存在する行

ここから、次のことが言える

  • 左の列と右の列の集合をとると、引数で指定した左のファイルの中身になる。
  • 中央の列と右の列の集合をとると、引数で指定した右のファイルの中身になる。

オプションで表示しない列を指定できる。 表示する列ではないことに注意せよ。

オプション 効果
-1 結果の1列名を表示しない
-2 結果の2列名を表示しない
-3 結果の3列名を表示しない
# left.txtにだけ存在する行を表示したいなら、2列目と3列目を表示しなければ良い。
% comm -23 left.txt right.txt
C
I
# right.txtにだけ存在する行を表示したいなら、1列目と3列目を表示しなければ良い。
% comm -13 left.txt right.txt
A
D
F
H