はじめに

こんにちは!今回はcommコマンドについて解説します。

commは2つのソート済みテキストファイルを比較して、共通している行や異なっている行を表示するコマンドです。データベースの差分チェックやリスト比較に活躍します。

ちょっと地味だけど、データ処理では超便利なコマンドですよ。

commコマンドとは

commは、2つのソート済みファイルを行ごとに比較するコマンドです。“compare"の短縮形ですね。

3列の出力に分けて、第1列は第1ファイルだけにある行、第2列は第2ファイルだけにある行、第3列は両方に共通する行を表示します。データセット比較に最適なコマンドです。

基本構文

1
comm [オプション] ファイル1 ファイル2

重要: 両方のファイルがソート済みである必要があります。未ソートだとおかしな結果になります。

主なオプション

オプション 説明
-1 第1ファイルだけの行を表示しない
-2 第2ファイルだけの行を表示しない
-3 共通する行を表示しない
--output-delimiter=文字列 列の区切り文字を変更
--check-order ソート順序をチェック

使用例

例1: 基本的な比較

1
comm file1.txt file2.txt

実行結果:

1
2
3
4
5
6
apple
 banana
  cherry
date
 elderberry
  fig

file1.txtにだけある行がインデント0、file2.txtにだけある行がインデント1、両方にある行がインデント2で表示されます。

例2: 第1ファイルだけの行を抽出

1
comm -23 file1.txt file2.txt

実行結果:

1
2
apple
date

-2-3を指定すると、第1ファイルだけに存在する行だけが表示されます。

例3: 第2ファイルだけの行を抽出

1
comm -13 file1.txt file2.txt

実行結果:

1
2
banana
elderberry

-1-3を指定すると、第2ファイルだけに存在する行だけが表示されます。

例4: 共通する行を抽出

1
comm -12 file1.txt file2.txt

実行結果:

1
2
cherry
fig

-1-2を指定すると、両方に存在する共通行だけが表示されます。

例5: 列の区切り文字を変更

1
comm --output-delimiter="|" file1.txt file2.txt

実行結果:

1
2
3
apple||
|banana|
||cherry

デフォルトのタブをパイプに変更します。CSV形式で出力したい時に便利。

例6: ソート順序をチェック

1
comm --check-order file1.txt file2.txt

ファイルが正しくソートされているか確認します。未ソートの場合はエラーが出ます。

例7: 数字ファイルの比較

1
comm <(sort numbers1.txt) <(sort numbers2.txt)

実行結果:

1
2
3
4
1
 2
  3
4

未ソートのファイルをソートしながら比較する場合はプロセス置換を使います。

例8: パイプとの組み合わせ

1
cat source.txt | sort | comm - sorted_target.txt

標準入力とファイルを比較します。-で標準入力を指定できます。

例9: ユーザー一覧の差分

1
comm -23 <(cut -d: -f1 /etc/passwd | sort) active_users.txt

システムユーザーのうち、非アクティブなユーザーを抽出する例。

例10: メールアドレスリストの比較

1
comm -3 old_list.txt new_list.txt | grep -v '^[[:space:]]'

古いリストと新しいリストで異なるメールアドレスを見つけます。

Tips・注意点

ファイルは必ずソート済みにする

commコマンドはソート済みファイル専用です。未ソートだと絶対に動きません。

1
2
3
4
# 未ソートの場合
sort file1.txt > sorted1.txt
sort file2.txt > sorted2.txt
comm sorted1.txt sorted2.txt

列の見分け方

デフォルト出力は見づらいので、オプションを組み合わせるのが普通です。

1
2
3
4
5
# これより
comm file1.txt file2.txt

# こっちの方がわかりやすい
comm --output-delimiter=',' file1.txt file2.txt

localeの影響

ソート順序はlocaleに依存します。安定した結果を得たい場合はLC_ALL=Cを使いましょう。

1
LC_ALL=C sort file.txt

実践的な使い方

ログファイルの差分抽出

1
comm -23 <(sort yesterday.log) <(sort today.log)

昨日のログにあるが今日のログにない行を抽出。問題検出に便利。

DNSレコード比較

1
comm -3 <(nslookup example.com | sort) <(cat known_records.txt | sort)

古いDNSレコードと現在のレコードの差分を確認。

パッケージの差分管理

1
comm -23 <(dpkg -l | awk '{print $2}' | sort) baseline_packages.txt

標準的なパッケージセットからインストール済みパッケージの差分を確認。

データベースの重複排除検証

1
comm -3 <(sort primary.txt) <(sort backup.txt)

プライマリとバックアップのデータセットが完全に一致しているか確認。

まとめ

commコマンドのポイント:

  • 2つのソート済みファイルを比較する専門コマンド
  • -1: 第1ファイルだけの行を非表示
  • -2: 第2ファイルだけの行を非表示
  • -3: 共通行を非表示
  • -23: 第1ファイルのみの行を抽出(最よく使う)
  • -13: 第2ファイルのみの行を抽出
  • -12: 共通行のみ抽出
  • ソート順序が重要!未ソートだと動かない

地味だけど、データ比較やリスト管理では極めて便利なコマンドです。sortと組み合わせると最強ですね。