diff コマンド:ファイルの比較と diff -u のパッチ形式、オプションまとめ

テスト環境RHEL系AlmaLinux 9.8rootアカウント

diff コマンドは、二つのファイルを行単位で比較し、異なる行だけを出力する Linux コマンドです。Web サーバーの設定をまねた古いファイルと新しいファイルを diff で比較して、変更された三か所を 2,3c2,3、5d4、6a6 の三行で確認し、-u オプションで保存したパッチファイルには同じ変更がマイナスとプラスの記号で整理されていました。

以下の出力のファイル名と内容、作業フォルダー /root/work は例の値です。比較したファイルはすべてテスト用に作った小さなファイルです。

1️⃣ diff コマンドの基本的な使い方と出力の読み方

コマンドの基本の形は diff、オプション、最初のファイル、二つ目のファイルの順です。最初のファイルを二つ目のファイルと同じにするには、どの行を変更し、削除し、追加すればよいかを行番号とともに出力します。

比較に使った二つのファイルは、Web サーバーの設定をまねた六行のファイルです。

cd /root/work
cat config-old.conf
# app config
listen 80
server_name example.com
root /var/www/html
gzip off
log_level warn
cat config-new.conf
# app config
listen 443
server_name example.com www.example.com
root /var/www/html
log_level warn
cache on

二つのファイルをオプションなしで比較しました。

diff config-old.conf config-new.conf
2,3c2,3
< listen 80
< server_name example.com
---
> listen 443
> server_name example.com www.example.com
5d4
< gzip off
6a6
> cache on
echo $?
1

出力には位置の行と内容の行が交互に出ます。位置の行の真ん中の文字 c は変更、d は削除、a は追加で、文字の左側は最初のファイル、右側は二つ目のファイルの行番号です。異なる箇所があると、終了コードは 1 です。

出力意味
2,3c2,3最初のファイルの 2~3 行目を二つ目のファイルの 2~3 行目に変更(change)
5d4最初のファイルの 5 行目を削除(delete)。削除すると二つ目のファイルの 4 行目の次とそろう
6a6最初のファイルの 6 行目の後に二つ目のファイルの 6 行目を追加(add)
< 行最初のファイルにある行
> 行二つ目のファイルにある行
---変更する行(c)で、最初のファイル側と二つ目のファイル側の境界

内容が同じファイルを比較すると、何も出力せず終了コード 0 で終わります。

diff config-old.conf config-copy.conf
echo $?
0

存在しないファイルを指定するとエラーメッセージが出て、終了コードは 2 です。

diff config-old.conf nosuch.conf
diff: nosuch.conf: No such file or directory
echo $?
2

スクリプトでは、この三つの値で「同じ」「異なる」「エラー」を区別します。

2️⃣ diff -u の統合形式とパッチファイル

既定の出力には変更された行しか出ないため、数百行ある設定ファイルでは、その行がどの設定の近くなのか見つけにくくなります。-u を付けると、変更された行の前後三行までまとめる統合形式(unified)で出力します。

diff -u config-old.conf config-new.conf
--- config-old.conf     2026-10-29 02:24:50.840228932 +0000
+++ config-new.conf     2026-10-29 02:24:50.840228932 +0000
@@ -1,6 +1,6 @@
 # app config
-listen 80
-server_name example.com
+listen 443
+server_name example.com www.example.com
 root /var/www/html
-gzip off
 log_level warn
+cache on

先頭の二行(---、+++)に二つのファイルの名前と更新時刻が出て、@@ -1,6 +1,6 @@ の行は、最初のファイルの 1 行目から 6 行と二つ目のファイルの 1 行目から 6 行をまとめたかたまり(hunk)です。その下の行は、先頭が - なら最初のファイルから削除した行、+ なら二つ目のファイルに追加した行、空白なら二つのファイルに同じようにある行です。

-c はコンテキスト形式(context)です。最初のファイルのかたまりと二つ目のファイルのかたまりを別々に出力し、変更された行の前には感嘆符、削除した行にはマイナス、追加した行にはプラスの記号が付きます。

diff -c config-old.conf config-new.conf
*** config-old.conf     Thu Oct 29 02:24:50 2026
--- config-new.conf     Thu Oct 29 02:24:50 2026
***************
*** 1,6 ****
  # app config
! listen 80
! server_name example.com
  root /var/www/html
- gzip off
  log_level warn
--- 1,6 ----
  # app config
! listen 443
! server_name example.com www.example.com
  root /var/www/html
  log_level warn
+ cache on

同じ変更でも、-c はそのままの行が二つのかたまりに一度ずつ出るため、-u より長くなりました。

-u の出力をファイルに保存すると、そのファイルがそのままパッチファイルになります。出力をファイルに送っても、diff の終了コードは 1 のままです。

diff -u config-old.conf config-new.conf > /root/work/config.patch
echo $?
1
cat /root/work/config.patch
--- config-old.conf     2026-10-29 02:24:50.840228932 +0000
+++ config-new.conf     2026-10-29 02:24:50.840228932 +0000
@@ -1,6 +1,6 @@
 # app config
-listen 80
-server_name example.com
+listen 443
+server_name example.com www.example.com
 root /var/www/html
-gzip off
 log_level warn
+cache on

保存したファイルの内容は、画面に出力した -u の結果と同じです。このファイルを patch コマンドに渡すと、最初のファイルを二つ目のファイルと同じ内容に変えられます。

3️⃣ diff オプションのまとめと空白、大文字と小文字の無視

設定を手で書き写すと、内容は同じなのに大文字と小文字や空白だけが異なる行ができます。二組目の例のファイルは、一行目の大文字 L を小文字に、二行目の空白一つを二つに変え、空行を一つ追加しました。

cat case-a.txt
Listen 80
ServerName example.com
DocumentRoot /var/www/html
cat case-b.txt
listen 80
ServerName  example.com

DocumentRoot /var/www/html
diff case-a.txt case-b.txt
1,2c1,3
< Listen 80
< ServerName example.com
---
> listen 80
> ServerName  example.com
>

オプションなしで比較すると、意味が同じ 1~2 行目も変更された行として出ます。-i で大文字と小文字を無視すると Listen の行が消え、最初のファイルの 2 行目だけが残ります。

diff -i case-a.txt case-b.txt
2c2,3
< ServerName example.com
---
> ServerName  example.com
>

-w を加えると行の中の空白をすべて無視するため、ServerName の行も同じ行になり、3 行目に追加した空行一つだけが残ります。-w の代わりに、空白の数だけを無視する -b を入れても、このファイルでは同じ結果になりました。

diff -i -w case-a.txt case-b.txt
2a3
>

-B まで付けると空行の違いも無視するため、出力なしで終了コード 0 で終わりました。

diff -i -w -B case-a.txt case-b.txt
echo $?
0

二つのファイルを左右に並べて見るときは -y を使います。既定の幅は 130 桁なので、-W 70 で狭めました。

diff -y -W 70 config-old.conf config-new.conf
# app config                            # app config
listen 80                         |     listen 443
server_name example.com           |     server_name example.com www.ex
root /var/www/html                      root /var/www/html
gzip off                          <
log_level warn                          log_level warn
                                  >     cache on

真ん中の縦線(|)は変更された行、< は最初のファイルにだけある行、> は二つ目のファイルにだけある行です。幅を狭めると長い行が切れます。server_name の行は、右側で www.ex までしか出ませんでした。

--suppress-common-lines を加えると、同じ行を除いて異なる行だけを残します。

diff -y --suppress-common-lines -W 70 config-old.conf config-new.conf
listen 80                         |     listen 443
server_name example.com           |     server_name example.com www.ex
gzip off                          <
                                  >     cache on

違いの内容ではなく、同じか異なるかだけを確認するときは -q を使います。ファイルが同じとき -q は何も出力しないため、同じだという一行を受け取るには -s を使います。

diff -q config-old.conf config-new.conf
Files config-old.conf and config-new.conf differ
diff -s config-old.conf config-copy.conf
Files config-old.conf and config-copy.conf are identical

オプションは下の 2 つのタブにまとめました。

オプションコピー説明
-u, --unified変更された行の前後三行までまとめる統合形式で出力
-c, --context最初のファイルのかたまりと二つ目のファイルのかたまりを別々に出力するコンテキスト形式
-i, --ignore-case大文字と小文字の違いを無視
-w, --ignore-all-space行の中の空白をすべて無視
-b, --ignore-space-change空白の数の違いだけを無視
-B, --ignore-blank-lines空行の違いを無視
-y, --side-by-side二つのファイルを左右に並べて出力
-W, --widthNUM並べて出力するときの幅を指定。既定値は 130 桁
--suppress-common-lines並べて出力するとき、同じ行を除いて異なる行だけを出力
-q, --brief同じか異なるかだけを出力。同じなら何も出力しない
-s, --report-identical-files二つのファイルが同じとき、同じだという一行を出力
-r, --recursiveサブフォルダー内のファイルまで比較
オプションコピー説明
-U, --unifiedNUM統合形式で一緒に出力する前後の行数を指定。既定値は 3
-N, --new-file片方にないファイルを空のファイルとして扱う
-x, --excludePAT名前がパターンに一致するファイルを比較から除外
-I, --ignore-matching-linesRE変更された行がすべて正規表現に一致すれば、その違いを無視
-Z, --ignore-trailing-space行末の空白を無視
-E, --ignore-tab-expansionタブを空白に変えて生じた違いを無視
-a, --textすべてのファイルをテキストとして扱う
--strip-trailing-cr行末のキャリッジリターンを取り除いて比較
--colorWHEN出力に色を付ける。WHEN は never、always、auto
-v, --versionバージョン情報を出力

🔲 diff コマンド シミュレーター

下のシミュレーターでは、本文の例のファイルで diff を直接入力できます。-u でパッチファイルを保存したり、-i -w -B、-rq で比較したりでき、config-new.conf に行を一つ追加してからもう一度比較すると、変わった結果が出ます。

diff コマンド シミュレーターdiff · rootアカウント
[root@server work]#
キーボードの↑↓で、前に入力したコマンドを呼び出せます。

4️⃣ diff -r でフォルダーを比較

サイトのファイルをデプロイする前後のように、複数のファイルをまとめて比較するときは、ファイルの代わりにフォルダー名を書きます。例のフォルダー site-v1 と site-v2 には index.html と css フォルダーが両方にあり、about.html と contact.html は片方にだけあります。

diff site-v1 site-v2
Only in site-v1: about.html
Only in site-v2: contact.html
Common subdirectories: site-v1/css and site-v2/css
diff site-v1/index.html site-v2/index.html
2,3c2,3
< <p>Version 1</p>
< <a href="about.html">About</a>
---
> <p>Version 2</p>
> <a href="contact.html">Contact</a>

オプションなしでフォルダーを比較すると、片方にだけあるファイルは [Only in] の行で、サブフォルダーは [Common subdirectories] の行でだけ出て、サブフォルダー内のファイルは比較しません。二つのフォルダーに同じ名前である index.html は、[diff site-v1/index.html site-v2/index.html] の行の下に違いを出力します。-r を付けると、css フォルダー内の style.css で変わった色の値まで出力します。

diff -r site-v1 site-v2
Only in site-v1: about.html
Only in site-v2: contact.html
diff -r site-v1/css/style.css site-v2/css/style.css
2c2
< h1 { color: #222; }
---
> h1 { color: #0a58ca; }
diff -r site-v1/index.html site-v2/index.html
2,3c2,3
< <p>Version 1</p>
< <a href="about.html">About</a>
---
> <p>Version 2</p>
> <a href="contact.html">Contact</a>

ファイルが多いフォルダーは、-rq で変更されたファイルの一覧から確認し、必要なファイルだけを diff でもう一度比較します。

diff -rq site-v1 site-v2
Only in site-v1: about.html
Only in site-v2: contact.html
Files site-v1/css/style.css and site-v2/css/style.css differ
Files site-v1/index.html and site-v2/index.html differ

🔢 FAQ & おすすめコンテンツ

cmp は二つのファイルをバイト単位で比較し、最初に異なる位置を一つだけ出力します。本文の二つの設定ファイルを cmp で比較した結果は [config-old.conf config-new.conf differ: char 21, line 2] の一行でした。行単位の比較に意味がない圧縮ファイルや画像が同じかどうかを確認するときに使います。

patch コマンドに元のファイルとパッチファイルを順に渡します([patch config-old.conf config.patch])。patch は元のファイルをその場で書き換えるため、-o で結果を別のファイルに書き出すか、コピーに先に適用します。

--color[=WHEN] オプションで色を付けられ、WHEN には never、always、auto を入れます。値を省略した --color は auto と同じで、端末に出力するときだけ色を付けるため、less のような別のコマンドに渡すときも色を残すには --color=always を使います。

ℹ️ 提携について
当サイトのコンテンツにはアフィリエイトリンクが含まれています。訪問者がこのリンクを通じて商品やサービスを購入すると、当サイトは販売元から手数料を受け取ります。この過程において、購入者が支払う金額(イベント割引適用で金額が下がります↓)は上昇しません。掲載されている価格・割引・在庫情報は作成時点のものであり、実際とは異なる場合がありますので、ご購入前に販売元にて最終確認をお願いいたします。商品の選定および評価は独自の基準に基づいて行われており、手数料の支払いの有無は紹介順や評価内容に影響を与えません。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

人間であることを証明してください: 5   +   3   =