Linux / コマンド / comm - ソートされた2つのファイルの共通・固有行の比較

commは整列された2つのファイルを行単位で比較し、1つ目のファイルだけの行、2つ目のファイルだけの行、共通の行を3列で表示します。

既定では、1つ目だけの行を1列目、2つ目だけの行を2列目、共通行を3列目に表示し、列はタブで区切ります。-1・-2・-3 は対応する列とその区切りを省く指定です。例えば -12 で共通列だけ残すと、列のための先頭タブは付きません。位置ごとの変更を読みたい場合はdiffによる差分表示を使います。

基本的な文法

comm [オプション] ソート済みファイル1 ソート済みファイル2

インストールされている実装とオプションは、配布版によって異なる場合があります。man commで現在のシステムの説明を確認してください。

使用例

3種類の行の見方

入力の行全体を同じ規則で並べ替えます。例えば LC_ALL=C sort old.txt > old.sorted と LC_ALL=C sort new.txt > new.sorted を使い、比較時も LC_ALL=C comm old.sorted new.sorted とそろえます。数値順や特定キーだけの順ではなく、comm の比較規則に合う順序が必要です。

comm old.sorted new.sorted

共通の行だけを出力

1列目と2列目を隠して3列目の共通列だけ残します。

comm -12 old.sorted new.sorted

2つ目のファイルにだけある行

1列目(1つ目だけ)と3列目(共通)を非表示にし、2つ目にだけある行を残します。

comm -13 old.sorted new.sorted

3列の結果と共通行を読み取る

commは最初のファイルだけにある行、二番目のファイルだけにある行、両方のファイルに共通する行を列で区別します。-12は前の二列を非表示にして共通行だけを残します。

printf 'apple\nbanana\n' > first.txt
printf 'banana\ncherry\n' > second.txt
comm -12 first.txt second.txt

例の出力:

banana

二つのファイルは同じロケールで事前にソートされている必要があります。ソートされていない入力では、列の意味を信頼することは難しいです。commは行の存在を比較し、diffは行位置を含む変更内容を表示するという違いも覚えておいてください。

主なオプションと形式

オプション・形式 説明
-1 最初のファイルだけにある行の列を非表示にします。
-2 二番目のファイルだけにある行の列を非表示にします。
-3 両方のファイルに共通する行の列を非表示にします。
--check-order GNU版で順序を厳密に確認し、不正なら診断して非0で終了します。途中の出力は使わないでください。

使用する際の注意点

ロケール(文字の比較規則)をそろえたsortによる並べ替えが必要です。重複行も1行ずつ対応させるため、片方に a が2行、他方に1行あれば、共通の a が1行と、片方だけの a が1行になります。値の有無だけの集合として比べたい場合は、両方の入力を同じ条件の sort -u で一意にしてください。comm は相違があっても正常終了なら0を返します。出力の有無と比較条件で結果を判断し、diff の「相違で1」と混同しないでください。

よくある質問

comm の結果の列は何を意味しますか?

1列目はファイル1にだけ、2列目はファイル2にだけ、3列目は両方のファイルに共通の行です。

公式ドキュメント

オプションの正確な動作と実装ごとの違いは、comm に関する公式ドキュメントで確認できます。