【Linux】diffコマンドの使い方|2つのファイルを比較・-u統一形式・終了コードでの判定

【diff】2つのファイルを比較する方法|見方・-u統一形式・終了コードでの判定 Linux

diffは、2つのファイル(またはディレクトリ)の内容を比較して、違いだけを表示するコマンドです。設定ファイルを編集する前後で何が変わったか確認する、2つのバージョンのソースコードの違いを調べるなど、Linux作業の様々な場面で使われます。git diffで見慣れている差分表示(-+で変更箇所を示す形式)も、元をたどればdiffコマンドの出力形式の1つです。

この記事では、実機のLinux(WSLのDebian)で実際にファイルを比較しながら、diffの基本的な出力の読み方から、スクリプトで使うための終了コードによる判定方法まで整理します。素のdiffの出力は最初とっつきにくく感じますが、読み方が分かれば強力な道具になります。

先に結論

  • 基本はdiff ファイルA ファイルB。差分がある行だけが表示されます。
  • <は1つ目のファイル、>は2つ目のファイルの内容です。
  • 見やすい表示には-u(unified形式・git diffと同じ見た目)を使います。
  • 差分の有無だけ知りたいときは-qを使います。
  • ディレクトリ同士を比較するには-r(再帰)を付けます。
  • 終了コードは、差分なし=0・差分あり=1・エラー=2で、スクリプトの分岐に使えます。

ファイルの中身を検索するgrep、行の置換・編集をするsed、コマンドの成否を判定するリダイレクトとパイプもあわせて参考になります。

スポンサーリンク

diffの基本と出力の読み方

diff ファイルA ファイルBで2つのファイルを比較します。出力の<は1つ目(A)の内容、>は2つ目(B)の内容を表します。

diff の基本
cat a.txt
# line1
# line2
# line3
# line4

cat b.txt
# line1
# LINE2
# line3
# line5

diff a.txt b.txt
# 2c2
# < line2
# ---
# > LINE2
# 4c4
# < line4
# ---
# > line5

実機でも、2行目と4行目に違いがある2つのファイルを比較すると、2c2(2行目がchange=変更)という見出しのあとに、<で1つ目のファイル(a.txt)の内容、区切り線---を挟んで>で2つ目のファイル(b.txt)の内容が表示されました。同じ内容の2つのファイルを比較すると、何も出力されません(差分がない、という結果)。cは変更(change)を表す記号で、ほかに追加された行を示すa(add)、削除された行を示すd(delete)もあります。

【重要】-uで見やすい統一形式にする

素のdiffの出力は、行数が多いと見づらくなります。-u(unified形式)を使うと、git diffと同じ見た目の、前後の文脈つき・+/-表記になり、断然読みやすくなります。

-u で unified形式
diff -u a.txt b.txt
# --- a.txt	2026-07-09 09:36:41 +0900
# +++ b.txt	2026-07-09 09:36:41 +0900
# @@ -1,4 +1,4 @@
#  line1
# -line2
# +LINE2
#  line3
# -line4
# +line5

実機でも、-uを付けると---/+++でファイル名とタイムスタンプが示され、@@ -1,4 +1,4 @@という位置情報のあとに、削除された行が-、追加された行が+、変わらない行が先頭スペースで表示されました。これはgitのdiffで見慣れている形式そのものです。素のdiff</>方式で「どこがAでどこがBか」を追うのがやや大変ですが、-uなら1行ずつの増減が直感的に読めます。実務では、ほぼ常に-uを付けて使うと考えてよいでしょう。

-q(差分の有無だけ)と-i(大文字小文字無視)

中身の詳細は要らず、「違うかどうか」だけを知りたいときは-qを使います。大文字・小文字の違いを無視して比較したいときは-iです。

-q と -i
# -q: 差分があるかどうかだけを表示(中身は見せない)
diff -q a.txt b.txt
# Files a.txt and b.txt differ

# -i: 大文字小文字を無視して比較
diff -i a.txt b.txt
# 4c4
# < line4
# > line5
#   ↑ line2 と LINE2 の違いは -i で無視され、4行目の違いだけが残った

実機でも、-qFiles a.txt and b.txt differという1行だけを表示し、中身の詳細は出しませんでした。大量のファイルを一括チェックして「違うものだけ」を洗い出したいときに便利です。-iを付けると、line2LINE2の大文字小文字だけの違いは無視され、内容が本当に異なる4行目(line4line5)だけが差分として残りました。設定ファイルなどで大文字小文字の表記ゆれを気にせず比較したいときに使えます。

-rでディレクトリ同士を比較する

diffはファイルだけでなく、-r(再帰)を付けるとディレクトリ同士を比較できます。中の各ファイルの差分に加えて、片方にしか存在しないファイルも報告してくれます。

-r でディレクトリ比較
diff -r dirA dirB
# diff -r dirA/f1.txt dirB/f1.txt
# 1c1
# < x
# > y
# Only in dirA: only_in_a.txt

実機でも、-rで2つのディレクトリを比較すると、両方に存在するf1.txtの中身の違いが表示され、さらにOnly in dirA: only_in_a.txtという形で片方にしか無いファイルまで報告されました。バックアップと現行のディレクトリを比較して「何が変わったか・何が増減したか」を一気に確認したいときに便利です。-r -qを組み合わせれば、変更されたファイルの一覧だけを手早く洗い出せます。

スクリプトで使うための終了コード

diffは、比較結果に応じて終了コードを変えるため、シェルスクリプトの条件分岐にそのまま使えます。差分なし=0、差分あり=1、エラー=2です。

終了コードによる判定
diff a.txt b.txt >/dev/null
echo $?     # 1(差分あり)

diff a.txt c.txt >/dev/null   # c.txt は a.txt のコピー
echo $?     # 0(差分なし)

diff a.txt nonexistent.txt >/dev/null 2>&1
echo $?     # 2(ファイルが存在しないなどのエラー)

# スクリプトでの使用例
if diff -q file_old.conf file_new.conf >/dev/null; then
  echo "設定に変更はありません"
else
  echo "設定が変更されています"
fi

実機でも、差分ありのケースでは1、差分なし(同一ファイル)では0、存在しないファイルを指定したエラーでは2と、それぞれ異なる終了コードが返ることを確認しました。01を明確に区別できるため、if diff ... ; then ... else ... fiという形で「設定ファイルが変更されたときだけ再起動する」といったデプロイスクリプトの分岐に組み込めます。2(エラー)も見分けられるので、「ファイルが存在しない」というケースを「差分なし」と誤判定する心配もありません。

主な書き方一覧

diffでよく使うオプションをまとめます。

書き方 働き
diff A B 基本の比較(</>形式)
diff -u A B unified形式(git diffと同じ見た目)
diff -q A B 差分の有無だけを表示
diff -i A B 大文字小文字を無視
diff -r A B ディレクトリを再帰的に比較
終了コード 0=差分なし / 1=差分あり / 2=エラー

よくある失敗

素のdiffの出力が読みにくい

</>形式は慣れが必要です。-uを付けるとgit diffと同じ形式で読みやすくなります。

差分の有無だけ知りたいのに全文が出る

-qを使うと、内容を表示せず「差分がある」ことだけを教えてくれます。

ディレクトリを指定して単純なdiffを使う

ディレクトリの比較には-rが必要です。付けないとエラーになります。

diffのエラーを差分なしと誤判定する

終了コードは0(差分なし)・1(差分あり)・2(エラー)の3種類です。混同しないよう注意します。

大文字小文字の違いだけで別物と判定してしまう

表記ゆれを無視したいときは-iを使います。

よくある質問

Qdiffの出力の見方を教えてください。
A<は1つ目のファイル、>は2つ目のファイルの内容を表します。2c2のような表示は「2行目がchange(変更)」を意味し、ほかに追加を表すa、削除を表すdもあります。素のままだと読みにくいので、-uを付けたunified形式(git diffと同じ見た目)がおすすめです。
Qgit diffと同じような見た目にするには?
A-uオプションを使います。diff -u ファイルA ファイルBとすると、削除された行が-、追加された行が+で表示される、unified形式になります。実機でも、この形式がgitで見慣れている差分表示と同じ見た目になることを確認しています。
Q2つのファイルが同じかどうかだけを確認したいです。
Adiff -q ファイルA ファイルBを使います。中身の詳細は表示せず、「Files A and B differ」のように差分の有無だけを教えてくれます。同一の場合は何も出力されません。大量のファイルを一括チェックしたいときに便利です。
Qdiffの結果をシェルスクリプトで判定するには?
A終了コードを使います。diffは差分なしのとき0、差分ありのとき1、エラー(ファイルが存在しないなど)のとき2を返します。if diff -q A B > /dev/null; then ... else ... fiのように書けば、差分の有無で処理を分岐できます。実機でも、この3つの終了コードがそれぞれ正しく返ることを確認しています。
Qディレクトリ同士を比較するには?
A-r(再帰)を付けます。diff -r ディレクトリA ディレクトリBとすると、両方に存在するファイルの中身の違いに加えて、片方にしか無いファイルも「Only in ディレクトリA: ファイル名」のように報告されます。バックアップと現行版の比較などに使えます。

まとめ

  • 基本はdiff A B<が1つ目、>が2つ目のファイルです。
  • 見やすさは-u(unified形式・git diffと同じ見た目)で解決します。
  • 有無だけなら-q、大文字小文字を無視するなら-i
  • ディレクトリ同士の比較は-rで、片方にしかないファイルも分かります。
  • 終了コード(0/1/2)でスクリプトの分岐に使えます。

diffは、地味に見えて「何が変わったか」を正確に把握するための欠かせないコマンドです。-uで見やすくし、終了コードでスクリプトに組み込めば、設定ファイルの変更検知やバックアップ比較など、幅広い自動化に活用できます。