Linux / コマンド / cmp - 2つのファイルをバイト単位で比較

cmpは二つのファイルをバイト単位で比較します。基本的に最初の相違を発見すると、バイト位置と行番号を知らせて終了するため、ファイルが完全に同じかどうかを迅速に確認したり、最初の不一致箇所を見つけるのに適しています。

この記事ではcmpの基本的な文法と主なオプション、実際の使用例、関連コマンドとの違い、使用時の注意点について説明します。

cmpコマンドとは?

2つの入力を先頭から比較し、比較範囲が同じなら通常は何も出力せず状態0、相違があれば1を返します。GNU版の比較エラーは通常2です。片方がもう片方の先頭部分と同じまま短い場合は、短い側のEOF(入力終端)を診断して状態1になります。標準エラーへの表示だけで比較エラーとは判断しないでください。位置と行番号は1から数えるため、一般的な0始まりのオフセットと区別します。行単位の変更を読む場合はdiffによるテキストの比較が役立ちます。

基本的な文法

cmp [オプション] ファイル1 [ファイル2 [SKIP1 [SKIP2]]]

オプションや詳細な動作は実装やバージョンによって異なる場合があります。現在のシステムではcmp --helpとman cmpでインストールされたコマンドの説明を確認してください。

cmpの基本的な使い方

2つのファイルを比較する

同じ場合は何も出力せず、違う場合は最初の相違位置を表示します。

cmp image-a.bin image-b.bin

出力なしで同一性を確認する

-sはメッセージを隠し、終了ステータスのみを使用します。

cmp -s copy.iso original.iso

最初の数バイトだけを比較する

GNU cmpの-nで比較する最大バイト数を制限します。

cmp -n 4096 file-a file-b

最初に異なるバイトの位置を読み取る

cmpは2つのファイルをバイト単位で比較し、最初に異なる位置を知らせます。同じファイルであれば、通常何も出力しません。

printf 'A' > first.bin
printf 'B' > second.bin
cmp first.bin second.bin

出力の例(文言は実装によって異なる場合があります):

first.bin second.bin differ: byte 1, line 1

終了ステータス1は差異があることを、2は読み取りエラーなどの問題を意味します。スクリプトで画面出力を望まない場合はcmp -sを使用して終了ステータスを確認してください。

主なオプション

オプション 説明
-s, --silent 差異の表示やエラーメッセージを抑え、終了状態で結果を返します。
-l, --verbose 異なるバイトの位置を10進数、値を8進数で列挙します。位置は1から数えます。
-b, --print-bytes 異なるバイトを表示可能な形で一緒に表示します。
-i SKIP 2つの入力の先頭部分を指定した分だけスキップします。
-i SKIP1:SKIP2 GNU実装では各入力のスキップ量を個別に指定します。
-n LIMIT 最大LIMITバイトまで比較します。

実践的活用例

スクリプトで変更の有無を確認する

以下を compare-config.sh に保存し、比較する2つのファイルを同じ作業場所に用意して sh compare-config.sh と実行します。状態0と1は表示を分け、比較できなかった場合は診断を表示してその終了状態を返します。この例では差異ありも処理できた結果として終了状態0で終わります。

if cmp -s generated.conf current.conf; then
  printf '%s\n' '変更なし'
else
  cmp_status=$?
  case "$cmp_status" in
    1) printf '%s\n' 'ファイルが異なる' ;;
    *) printf '比較エラー(終了状態 %s)\n' "$cmp_status" >&2
       exit "$cmp_status" ;;
  esac
fi

ヘッダー部分だけ比較する

形式の固定ヘッダーサイズがわかる場合に比較範囲を制限できます。ただし -n は最大バイト数であり、両方が短く同じ内容なら、指定数を読めなくても状態0になります。必要ならファイル長も先に確認してください。

cmp -n 512 disk-a.img disk-b.img

オフセットをスキップして比較する

比較から除外する領域がある場合に、先頭から読み飛ばすバイト数を指定します。両方のファイルがスキップ量より短い場合も空の入力同士として一致するため、想定した領域が存在するかを別に確認します。スキップした部分や指定範囲外まで同一とは判断できません。

cmp -i 4096 payload-a.bin payload-b.bin

cmp と関連するコマンドの比較

コマンド 主な役割 適した状況
cmp バイト単位での最初の違い 同一性と最初のオフセット
diff 行単位のテキストの違い 人が読む変更内容
sha256sum 各ファイルのハッシュ計算 リモート・複数ファイルの整合性比較
comm 整列された行集合の比較 共通・固有項目の分離

使用する際の注意点

-l 出力は非常に大きくなる可能性があります

大きなファイルで差が多い場合、すべてのバイトの差を出力するため、まず基本モードや -s で確認します。

終了状態を区別する

1 はファイルが異なることを示し、2 以上は比較自体のエラーである可能性があるため、スクリプトで別途処理します。

バイトが同じでもファイルの意味まで検証されるわけではありません

同一バイトかどうかは確認しますが、署名、出所、ファイル形式の有効性は検証しません。

FAQ

cmp 出力がない場合は同じファイルですか?

コマンドが正常に終了し、状態が 0 であれば、比較した範囲のバイトは同じです。

最初の差異以降の相違も一覧で見るには?

cmp -l ファイル1 ファイル2を使用しますが、差異が多いと出力が非常に大きくなる可能性があります。

テキストファイルもcmpで比較できますか?

可能ですが、変更された行を読みやすく見るにはdiffの方が適しています。

チェックサム比較とは何が違うのですか?

cmpは2つのファイルを直接同時に読み比べますが、チェックサムは各ファイルの要約値を計算して異なる場所でも比較しやすくします。

参考資料