シェル: 2 つのファイルの共通行・差分行は comm で取る
「ファイル a と b の両方にある行」を、a の各行で b を grep して探すのは遅くて壊れやすい。ソート済みの 2 ファイルなら comm 1 発で、共通行・片方にだけある行を取り出せる。
使う場面
- 2 つのリスト(ユーザー ID、パッケージ名、ホスト名など)の共通部分・差分を取りたいとき
- 「前回の一覧にはなく今回増えたもの」を出したいとき
やり方
comm は 3 列を出す: 1 列目 = a だけ、2 列目 = b だけ、3 列目 = 両方。-1 -2 -3 で消す列を選ぶ。
sh
# 両方にある行(共通部分)
comm -12 <(sort -u a.txt) <(sort -u b.txt)
# a にだけある行
comm -23 <(sort -u a.txt) <(sort -u b.txt)
# b にだけある行(新しく増えたもの)
comm -13 <(sort -u old.txt) <(sort -u new.txt)注意点
- 入力はソート済みが前提。
<(sort ...)(bash / zsh のプロセス置換)で渡すのが定番。sh(dash)では使えないので一時ファイルにソートしておく。 - ロケールによってソート順が変わり、
commが「ソートされていない」と警告することがある。LC_ALL=C sortとLC_ALL=C commで揃えると安全。 - 行末の空白や CRLF の違いで一致しないことがある。必要なら
tr -d '\r'で正規化する。 grep -Fxf b.txt a.txtでも共通行は取れる(固定文字列・行全体一致)。順序を保ちたいときはこちら。
出典
- @mattn_jp 2026-07-03: @mattn_jp · 2026-07-03