Linux 講座 / ファイル比較 - diffとcmpの違いと実習
2つのファイルでどの行がどのように変わったかを確認するにはdiffを、バイト単位で同じかどうかを素早く判定するにはcmpを使用します。両方のコマンドとも、ファイルが異なる場合は通常終了ステータス1を返しますが、これはコマンド自体のエラーを意味するステータス2とは異なります。この講座では、小さなファイル2つで出力と終了ステータスを一緒に確認します。
比較するファイルを準備して読み込む方法はファイル内容の確認を参照してください。diffのステータス1は通常の実行失敗ではなく差異があることを意味するので、終了ステータスと条件付き実行に接続するときには区別する必要があります。
比較するファイルの準備
以下の実習はBashとGNU Diffutilsを基準としています。~/linux-course-13-practiceがすでに存在する場合は別の名前を付けてください。最初のmkdirが失敗した場合は、その後のファイル作成コマンドを実行しないでください。>は既存のファイルを上書きできます。
mkdir ~/linux-course-13-practice
cd ~/linux-course-13-practice
pwd
位置が正しければ、2つのファイルを作成します。2行目だけが beta と BETA で異なります。
printf 'alpha\nbeta\ngamma\n' > old.txt
printf 'alpha\nBETA\ngamma\n' > new.txt
diffで行の変更内容を読む
diff は行単位の差異を示します。-u は周囲の変わらない行まで一緒に表示する統合形式です。GNU diff の --label を使うと、ファイル修正時刻の代わりに一定のヘッダーを付けて例を読みやすくできます。
diff -u --label old --label new old.txt new.txt
この演習の出力は次の通りです。
--- old
+++ new
@@ -1,3 +1,3 @@
alpha
-beta
+BETA
gamma
--- は前のファイル、+++ は新しいファイルを表します。@@ 行は比較中の行範囲を、前に - が付いた行は以前の内容、+ が付いた行は新しい内容を意味します。前に空白のある行は両方のファイルで同じです。名前が似ているからといって、どちらのファイルが「元のもの」かを diff が判断するわけではありません。コマンド引数の順序が比較の方向を決定します。
cmpで最初のバイトの違いを確認する
cmpはファイルをバイト単位で比較し、基本的な出力は最初の違いが見つかった位置を知らせます。この例では、最初の行alphaと改行の後の、二行目の最初の文字が異なります。
cmp old.txt new.txt
英語ロケールのGNU cmpではold.txt new.txt differ: byte 7, line 2のように表示されることがあります。ファイル名や言語設定によって文言は異なっても、最初の違いが二行目にあることは同じです。この既定の表示は、その後のすべての違いを列挙するものではありません。
出力なしで同一・相違のみを知りたい場合は-sを付けた後、すぐに終了ステータスを確認してください。下記のコマンドは実習ファイルが異なるため1を出力します。$?は直前に実行したコマンドの終了ステータスなので、その間に他のコマンドを入れると結果が変わります。
cmp -s old.txt new.txt
echo $?
違いがある結果と実行エラーを区別する
| 終了ステータス | diff・cmpでの一般的な意味 | 次の行動 |
|---|---|---|
0 |
違いなし | 比較対象と基準が合っているか確認 |
1 |
差異を発見 | diff の出力で変わった部分を確認 |
2 |
ファイルアクセス失敗などの問題 | パス・権限・エラーメッセージを確認 |
バイトが同じかどうかは cmp、テキスト変更内容を読む作業は diff -u が適しています。行末形式やエンコーディングが異なると、目で見たときに似ていても差異が生じることがあります。バイナリファイルはテキスト diff が有用な説明を提供できない場合があるため、cmp で同一性をまず確認してください。ディレクトリツリーを比較する必要がある場合は、GNU diff -r を使用できますが、対象範囲が広がるため、まずパスを確認する必要があります。
公式ドキュメント
GNU Diffutils 公式マニュアル で統合 diff 形式、cmp の出力と二つのコマンドの終了ステータスを確認できます。




