diff(1) 2 つのファイル間の違いを探す

書式

diff [-abcdefhilnpqrstuwyBEHNPT] [-LINES] [-x PATTERN] [-C LINES] [-D NAME] [-F REGEXP] [-I REGEXP] [-L LABEL] [-S FILE] [-U LINES] [-W COLUMNS] [-X FILE] [--binary] [--brief] [--changed-group-format=fORMAT] [--context[=LINES]] [--diff-program=PROGRAM] [--ed] [--exclude=PATTERN] [--exclude-from=FILE] [--expand-tabs] [--forward-ed] [--from-file=FILE] [--horizon-lines=LINES] [--ifdef=NAME] [--ignore-all-space] [--ignore-blank-lines] [--ignore-case] [--ignore-file-name-case] [--ignore-matching-lines=REGEXP] [--ignore-space-change] [--ignore-tab-expansion] [--inhibit-hunk-merge] [--initial-tab] [--label=LABEL] [--left-column] [--line-format=FORMAT] [--minimal] [--new-file] [--new-group-format=FORMAT] [--new-line-format=FORMAT] [--no-ignore-file-name-case] [--old-group-format=FORMAT] [--old-line-format=FORMAT] [--paginate] [--rcs] [--recursive] [--report-identical-files] [--sdiff-merge-assist] [--show-c-function] [--show-function-line=REGEXP] [--side-by-side] [--speed-large-files] [--starting-file=FILE] [--strip-trailing-cr] [--supress-common-lines] [--text] [--to-file=FILE] [--unchanged-group-format=FORMAT] [--unchanged-line-format=FORMAT] [--unidirectional-new-file] [--unified[=LINES]] [--width=COLUMNS] FROMFILE TOFILE

diff [-v] [--help] [--version]

説明

diff は 2 つのファイルを比較し、それらの違いを記述して出力する。

もっとも簡単な場合は、比較対象のファイルは FROMFILETOFILE である。これらのファイルのうちのどちらかは `-' と指定しても良い。この時はそのファイルは標準入力から読み込まれる。

FROMFILE がディレクトリで TOFILE がディレクトリではない場合、 diff はディレクトリ FROMFILE にある、ファイル名が TOFILE のファイルを比較対象にする (逆も同様)。 ディレクトリでない方の指定を `-' にすることはできない。

両方がディレクトリのときは、 diff は双方のディレクトリにある、対応するファイルを アルファベット順にそれぞれ比較する。 比較は再帰的には行われないが、 -r または --recursive オプションを指定すれば再帰的になる。 diff はディレクトリの内容そのものをファイルのように比較することはしない。 フルパス指定のファイルは `-' であってはならない。なぜなら標準入力には名前がないので、 「同名のファイル」という概念が使えないからである。

--from-file=FILE オプションが与えられると、任意の数のファイル名を与えることができ、 それぞれのファイルは FILE と比較される。 同様に、 --to-file=FILE オプションが与えられると、それぞれ指定されたファイルは FILE と比較される。 [訳注: 2.7 にはこれらのオプションは存在しない]

オプション

-LINES
異なっている部分の前後 LINES 行 (整数) 分のコンテクストを表示する。 このオプションは出力形式自体の指定は行わない。 したがって -c-u オプションと一緒に用いないと、なんの効果も持たない。 このオプションは obsolete である。 patch(1) が正しく動作するには、少なくとも 2 行のコンテクストが必要である。
-a, --text
ファイルがテキストには見えないような場合でも、 全てのファイルをテキストとみなして 1 行ずつ比較を行う。
-b, --ignore-space-change
スペースの数だけが違う場合には違いを無視する。 不完全な行は無視される。
-c
context 出力形式を用いる。
-d, --minimal
アルゴリズムを変更し、より小さな差分が生成できるようにする。 これを使うと diff は遅くなる (非常に遅くなる場合もある)。
-e, --ed
ed(1) のスクリプト形式で出力する。
-f, --forward-ed
ed のスクリプトと一見同じような出力をする。 しかし出力に現れる順序が異なる [訳注: したがって ed では使えない]。
-h
現在は何も効果を持たない。Unix との互換性のために存在している。 これは推奨されない。
-i, --ignore-case
英大文字と小文字の違いを無視する。
-l, --paginate
出力を pr(1) に通してページ付けを行う。
-n, --rcs
RCS 形式の diff を出力する。 -f と似ているが、それぞれのコマンドは処理する行数を指定する。
-p, --show-c-function
変更がどの C 関数で行われたのかを表示する。 `-F'^[_a-zA-Z$]'' と同じ。
-q, --brief
ファイルが違うかどうかだけを報告する。 違いの詳細は報告しない。
-r, --recursive
ディレクトリを比較するとき、 見付かったサブディレクトリをすべて再帰的に比較する。
-s, --report-identical-files
2 つのファイルが同じだったときも報告する。
-t, --expand-tabs
入力ファイルでのタブによる位置あわせを保存するため、 出力のタブをスペースに展開する。
-u
unified 出力形式を用いる。
-w, --ignore-all-space
行を比較するときスペースを無視する。 不完全な行は無視される。
-x PATTERN, --exclude=PATTERN
ディレクトリを比較するとき、 ファイル名の base 部が PATTERN にマッチするファイルやサブディレクトリを無視する。
-y, --side-by-side
side-by-side 出力形式を用いる。
-B, --ignore-blank-lines
空行を挿入・削除するだけの変更を無視する。
-C LINES, --context[=LINES]
context 出力形式を用い、 LINES 行 (整数値) のコンテクストを表示する。 LINES が与えられなければ 3 行表示する。 patch が正しく動作するためには、 少なくとも 2 行のコンテクストが必要であることが多い。
-D NAME, --ifdef=NAME
if-then-else 形式でマージされた出力を行い、 プリプロセッサの条件マクロに NAME を用いる。
-E, --ignore-tab-expansion
タブ展開によるスペースの変更を無視する。
-F REGEXP, --show-function-line=REGEXP
context 形式と unified 形式において、 各差分 hunk (テキストブロック) に対し、 その前方で REGEXP にマッチした最後の行の一部を表示する。
-H, --speed-large-files
小さな変更が大量にあるような大きなファイルを高速に扱うために、 ヒューリスティックな手法を用いる。 短縮形式 -H は推奨されなくなった。
-I REGEXP, --ignore-matching-lines=REGEXP
REGEXP にマッチするような行を挿入・削除するだけの変更を無視する。
-L LABEL, --label=LABEL
context 形式と unified 形式のヘッダに、 ファイル名ではなく LABEL を用いる。 短縮形式 -L は推奨されなくなった。
-N, --new-file
ディレクトリを比較する際、 片方のディレクトリにのみファイルが存在していたら、 もう片方のディレクトリには同名の空っぽのファイルがあるように動作する。
-P, --unidirectional-new-file
ディレクトリを比較する際、 2 番目のディレクトリにのみファイルが存在していたら、 1 番目のディレクトリには同名の空っぽのファイルがあるように動作する。 短縮形式 -P は推奨されなくなった。
-S FILE, --starting-file=FILE
ディレクトリを比較する際、 FILE から始める。中断した比較を続行する際に利用できる。
-T, --initial-tab
normal 形式や context 形式で、テキストの前にスペースでなくタブを出力する。 こうすると行中でのタブによる桁揃えが普通に見える。
-U LINES, --unified[=LINES]
unified 出力形式を用い、 LINES 行 (整数値) のコンテクストを表示する。 LINES が与えられなければ 3 行表示する。 patch が正しく動作するためには、 少なくとも 2 行のコンテクストが必要であることが多い。
-W COLUMNS, --width=COLUMNS
side-by-side 形式で、出力の幅を COLUMNS にする。
-XFILE, --exclude-from=FILE
ディレクトリを比較する際、 ファイル名の base 部が FILE のパターンのいずれかにマッチするファイルやサブディレクトリを無視する。
--binary
データをバイナリモードで読み書きする (Linux やその他の POSIX ホストでは意味なし)。
--changed-group-format=FORMAT
if-then-else 形式で、 両方のファイルで異なる行グループの出力に FORMAT を用いる。
--diff-program= PROGRAM
ファイルの比較するために diff と互換性のある 外部プログラム PROGRAM を用いる。
--from-file=FILE
FILE を各オペランドと比較する (FILE はディレクトリでも良い)。 [訳注: 2.7 にはこのオプションは存在しない]
--horizon-lines=LINES
差分をもっともコンパクトに出力するために、 違う部分の前後にある共通部分のそれぞれ LINES 行を捨てずに保存する。
--ignore-file-name-case
ファイルを比較する際にファイル名の大文字小文字を無視する。 そのため ``foo'' と ``Foo'' は同じとされるので、互いに比較される。
--inhibit-hunk-merge
隣接する hunk の境界を移動して hunk をマージする動作を行わない。
--left-column
side-by-side 形式で、共通な行は左側の列にしか表示しない。
--line-format=FORMAT
if-then-else 形式で、全ての入力行の出力に FORMAT を用いる。
--new-group-format=FORMAT
if-then-else 形式で、 2 番目のファイルだけにある行グループの出力に FORMAT を用いる。
--new-line-format=FORMAT
if-then-else 形式で、 2 番目のファイルだけにある行の出力に FORMAT を用いる。
--no-ignore-file-name-case
ファイルを比較する際に、ファイル名の大文字小文字を考慮する。 そのため ``foo'' と ``Foo'' は同じものとされない。 --ignore-file-name-case を参照すること。
--old-group-format=FORMAT
if-then-else 形式で、 1 番目のファイルだけにある行グループの出力に FORMAT を用いる。
--old-line-format=FORMAT
if-then-else 形式で、 1 番目のファイルだけにある行の出力に FORMAT を用いる。
--sdiff-merge-assist
sdiff(1) 用に追加情報を表示する。 sdiffdiff を実行するときにこのオプションを用いる。 通常のユーザーがこのオプションを直接指定する場合はあまり想定されていない。
--strip-trailing-cr
行末の CR を取り除く。 行末のマーカとして CRLF を使うシステムの出力を処理するときに役立つ。
--suppress-common-lines
side-by-side 形式で共通な行を表示しない。
--unchanged-group-format=FORMAT
if-then-else 形式で、 両方のファイルに共通な行グループの出力に FORMAT を用いる。
--unchanged-line-format=FORMAT
if-then-else 形式で、 両方のファイルに共通な行の出力に FORMAT を用いる。
--help
標準出力に使用方法のメッセージを出力して正常終了する。
-v, --version
diff のバージョン番号を出力する。

出力の形式

context 形式

context 出力形式は 2 行のヘッダからはじまる。 これは以下のようなものである:

*** FROMFILE FROMFILE-MODIFICATION-TIME
--- TOFILE TOFILE-MODIFICATION-TIME

-L LABEL を用いるとヘッダの内容は変化する。 次に来るのは hunk (テキストブロック) である。 繰り返し登場することもある。 context 形式の hunk は以下のようなものである:

***************
*** FROMFILE-LINE-RANGE ****
  FROMFILE-LINE
  FROMFILE-LINE...
--- TOFILE-LINE-RANGE ----
  TOFILE-LINE
  TOFILE-LINE...

異なっている行の周辺のコンテクストの各行には、 先頭に 2 つのスペースがついている。 2 つのファイル間で異なっている行には、 先頭に表示文字とスペースがつく。

!
2 つのファイル間で変更された部分の各行。 もう一方のファイルの対応する部分も `!' でマークされて表示される。
+
2 つめのファイルで「挿入された」行。1 つめのファイルに対応部分はない。
-
1 つめのファイルで「削除された」行。2 つめのファイルに対応部分はない。

hunk の全ての変更が挿入であれば、 FROMFILE 各行は省略される。また全ての変更が削除であれば、 TOFILE 各行は省略される。

unified 形式

--- FROMFILE FROMFILE-MODIFICATION-TIME
+++ TOFILE TOFILE-MODIFICATION-TIME

-L LABEL を用いるとヘッダの内容は変化する。 次に来るのは hunk (テキストブロック) である。繰り返し登場することもある。 それぞれの hunk はファイルの異なっている 1 つ 1 つの部分を示している。 unified 形式の hunk は以下のようなものである:

@@ FROMFILE-RANGE TOFILE-RANGE @@
LINE-FROM-EITHER-FILE
LINE-FROM-EITHER-FILE...

両者で共通な行の前には 1 つのスペースが置かれる。 異なる行の前には以下の表示文字が置かれる:

+
ここで 1 つめのファイルに行の追加が行われた。
-
ここで 1 つめのファイルから行の削除が行われた。

side-by-side 形式

ファイルは 2 列に表示され、間にのど (gutter) が置かれる。 のどには以下のマーカーのいずれか 1 つが含まれる。
[訳注]:
「のど (gutter)」とは、印刷用語で左右のページの間にある部分 (すなわち、 折り目になるところ) を指す。
` '
対応する行が共通である。つまり、両方の行が同一であるか、 違いが --ignore オプションのいずれかによって無視された。
|
対応する行が異なる。両方とも完全か、両方とも不完全かである。
<
ファイルは異なり、1 番目のファイルにだけこの行が含まれている。
>
ファイルは異なり、2 番目のファイルにだけこの行が含まれている。
(
1 番目のファイルにだけこの行が含まれているが、違いは無視される。
)
2 番目のファイルにだけこの行が含まれているが、違いは無視される。
\
対応する行が異なる。1 番目の行だけに行末の改行がない。
/
対応する行が異なる。2 番目の行だけに行末の改行がない。 通常出力行は、そこに含まれる行の末尾に改行がない場合に限って改行されない。 しかし、出力行が 2 行の差異を表している場合には、 片方だけに改行がない場合もあり得る。この場合出力行には改行が出力されるが、 のどのマークは 1 番目の行末に改行がなければ `\' に、2 番目の行末に改行がなければ `/' になる。

side-by-side 形式が一番読みやすいような場合もあるが、限界もある。 この形式は通常よりもずっと広い幅の出力を生成し、 長すぎる行は折り畳んでしまう。 またこの出力では通常よりも文字の整列への依存が大きくなるので、 等幅フォントを使っていなかったり、通常と異なるタブストップを使っていたり、 印字されない文字を使っていたりすると、出力が非常に醜くなる。

ed(1) 形式

1 つ以上の差分 hunk から構成される。 末尾に近い方の変更が先に現れ、行数の変化が以降の ed の行番号解釈に影響しないようになっている。 ed 形式の hunk は以下のようなものである:

CHANGE-COMMAND
TO-FILE-LINE
TO-FILE-LINE...
.

ed は入力の末尾を表すためにピリオド 1 つだけの行を用いるので、 diff は変更された行のうち、ピリオド 1 つだけの行を ピリオド 2 つに変更してプロテクトし、 続けて 2 つのピリオドを 1 つにする ed コマンドを書く。 ed 形式は改行されていない行を表すことができない。 したがって 2 番目のファイルの最終行が変更されていて、 かつ改行されていなかった場合、 diff はエラーを報告して、改行があるかのように動作する。

変更コマンドには 3 つの種類がある。 それぞれ、1 番目のファイルの行番号 (またはコンマ区切り指定の行範囲指定)、 続けて変更の種類を示す 1 文字の文字からなる。 行番号は、すべてファイルのオリジナルの行番号である。 変更コマンドの種類は以下の通り:

La
1 番目のファイルの L 行目以降に、2 番目のファイルからテキストを追加する。 例えば `8a' は、以降の行をファイル 1 の 8 行目以降に追加する。
Rc
1 番目のファイルの行範囲 R を、 引き続く行で置き換える。追加と削除の組み合わせでも同じことができるが、 こちらのほうがコンパクトである。例えば `5,7c' はファイル 1 の 5 行目から 7 行目をファイル 2 から読み込んだ内容で置き換える。
Rd
1 番目のファイルの行範囲 R を削除する。 例えば `5,7d' はファイル 1 の 5 行目から 7 行目までを削除する。

diffed スクリプトのような出力で、かつ各 hunk が forward 方向 (先頭から末尾へ) のような出力も生成できる。コマンドの形式もちょっと変化している。 コマンド文字が、修正する行や行範囲の先に来るのである。 また、ピリオド 1 つだけの行を特別扱いすることもしない。 ed 形式と同様に、forward ed 形式も改行していない行を表すことはできない。

forward ed 形式はあまり便利ではない。なぜなら edpatch もこの形式の diff を用いることができないからである。 これは主に古いバージョンの diff との互換性のために存在している。

RCS 形式

RCS 出力形式は Revision Control System (RCS) で用いるために特別に設計されたものである。 RCS はバージョンやシステムの異なるファイルを扱うための、 フリーなプログラムセットである。 この形式は forward ed 形式と似ているが、 ピリオド 1 つの行や改行していない行の問題を回避しているので、 ファイル内容の任意の変更を表すことができる。 テキストセクションをピリオド 1 つの行で終わるのではなく、 それぞれのコマンドで、適用する行数を指定しているのである。また `c' コマンドの代わりに `a' と `d' の組み合わせを用いている。 さらに 2 番目のファイルの末尾が変更されていて、 かつ改行で終わっていない場合には、 出力の末尾も改行されない状態で終わる。

IF-THEN-ELSE

C ソース形式

diff を用いて 2 ファイルの C ソースコードをマージすることもできる。 この出力形式には、両方のファイルの行がすべて含まれる。 両方のファイルに共通な行は一度しか登場しない。 異なる部分は C プリプロセッサの指定を用いて分離される。 #ifdef NAME または #ifndef NAME, ,BR #else ", and " #endif である。 出力をコンパイルするとき、マクロ NAME を定義したり、未定義のままにすることによって、 どちらのバージョンを使うかを選択できる。
  例えば、`wait (&s)' というインスタンスを `waitpid (-1, &s, 0)' に変更し、新旧のファイルを `--ifdef=HAVE_WAITPID' オプションによってマージすると、 影響を受けた部分のコードは以下のようになるだろう:

    do {
 #ifndef HAVE_WAITPID
          if ((w = wait (&s)) < 0 && errno != EINTR)
 #else /* HAVE_WAITPID */
          if ((w = waitpid (-1, &s, 0)) < 0  &&  errno != EINTR)
 #endif /* HAVE_WAITPID */
          return w;
    } while (w != child);

行グループ形式

行グループ形式を用いると、 if-then-else 入力を受け入れる多くのアプリケーションに適した形式を指定できる。 例えばプログラミング言語や文書整形言語などが挙げられる。 行グループ形式は、 似ている行からなる隣接したグループの出力形式を指定する。

例えば、以下のコマンドは TeX ファイル `old' と `new' を比較し、 old の部分を `\begin{em}'-`\end{em}' で囲み、 new の部分を `\begin{bf}'-`\end{bf}' で囲んでマージしたかたちで出力する。

 diff \
    --old-group-format='\begin{em}
 %<\end{em}
 '  \
    --new-group-format='\begin{bf}
 %>\end{bf}
 '  \
    old new

以下のコマンドも上記の例と同じだが、やや記述が多い。 デフォルトの行グループ形式も指定しているからである。

 diff \
    --old-group-format='\begin{em}
 %<\end{em}
 ' \
    --new-group-format='\begin{bf}
 %>\end{bf}
 ' \
    --unchanged-group-format='%=' \
    --changed-group-format='\begin{em}
 %<\end{em}
 \begin{bf}
 %>\end{bf}
 '  \
    old new

次にもう少し進んだ例を紹介する。これは差分リストを、
 "plain English" スタイルで行番号を書いたヘッダとともに出力する。

 diff \
    --unchanged-group-format='' \
    --old-group-format='-------- %dn line%(n=1?:s) deleted at %df:
 %<' \
    --new-group-format='-------- %dN line%(N=1?:s) added after %de:
 %>' \
    --changed-group-format='-------- %dn line%(n=1?:s) changed at %df:
 %<-------- to:
 %>' \
    old new

行グループ形式を指定するには、 diff を以下のオプションのどれか 1 つを指定して実行する。 4 つまでの行グループ形式を指定でき、 各指定がそれぞれ行グループ 1 つに対応する。 FORMAT にはシェルのメタキャラクタが入っていることが多いので、 クォートするべきであろう。

--old-group-format=FORMAT
これらの行グループは 1 番目のファイルだけにある行からなる hunk である。 デフォルトの old グループ形式は、changed グループ形式が指定されていれば それと同じになる。されていなければ行グループはそのままのかたちで出力される。
--new-group-format=FORMAT
これらの行グループは 2 番目のファイルだけにある行からなる hunk である。 デフォルトの new グループ形式は、changed グループ形式が指定されていれば それと同じになる。されていなければ行グループはそのままのかたちで出力される。
--changed-group-format=FORMAT
これらの行グループは両方のファイルの行からなる hunk である。 デフォルトの changed グループ形式は、 old グループと new グループの形式を連結したものである。
--unchanged-group-format=FORMAT
これらの行グループは両方のファイルに共通の行からなる hunk である。 デフォルトの unchanged グループ形式は、 行グループをそのままのかたちで出力するものである。

グループ変換

%<
1 番目のファイルからの行を意味する。行末尾の改行も含む。 各行は old 行形式によって整形される。
%>
2 番目のファイルからの行を意味する。行末尾の改行も含む。 各行は new 行形式によって整形される。
%=
両方のファイルで共通な行を意味する。行末尾の改行も含む。 各行は unchanged 行形式によって整形される。
%%
`%' を表す。
%c'C''
ここで C は文字 1 文字で、C を表す。 C にバックスラッシュやアポストロフィは指定できない。 例えば `%c':'' はコロンを表し、これは if-then-else 形式の then 部分でもコロンとして解釈される。通常はコロンは then 部分の終わりとして扱われる。
%c'\O''
ここで 0 は 1 桁から 3 桁までの 8 進数字であり、8 進のコード 0 に対応する文字を表す。例えば `%c'\0'' はナル文字になる。
(A=B?T:E)
AB に等しい場合は T、 等しくない場合は EAB はそれぞれ 10 進数の定数か、上記のように解釈される文字 1 つである。 この形式指定は A の値が B と等しければ T と等価であり、 それ以外の場合は E と等価である。

例えば `%(N=0?no:%dN) line%(N=1?:s)' は N (new ファイルからのグループの行数) が 0 なら `no lines' となり、 N が 1 なら `1 line' となり、それ以外の場合は `%dN lines' となる。

FN
ここで Fprintf(3) の変換指定で、 N は以下の文字のどれかである。 「F で整形された N の値」 を表す。
e
old ファイルからのグループの直前の行の行番号。
f
old ファイルからのグループの最初の行番号。e + 1 に等しい。
l
old ファイルからのグループの末尾の行番号。
m
old ファイルからのグループの直後の行の行番号。l + 1 に等しい。
n
old ファイルからのグループの行数。l - f + 1 に等しい。
E, F, L, M, N
上記と同様の new ファイルからのグループのもの。

printf 変換指定には %d, %o, %x, %X (それぞれ 10 進, 8 進, 小文字 16 進, 大文字 16 進) が使える。 `%' の後には以下のオプションを順に指定できる。 `-' (左詰めの指定)、整数 (フィールドの最低幅)、 ピリオドと数値 (数値は省略可; 桁数の最小値) である。 例えば `%5dN' は new ファイルからのグループの行数を、 5 文字幅のフィールドに、 printf の "%5d" 書式を用いて表示する。

行形式

行形式は、入力から取得された各行を if-then-else 形式の 行グループとして出力される際の制御を行う。
    例えば、以下のコマンドは、テキストの左に変更表示の 1 文字を表示して テキストを出力する。出力の最初の桁は、削除行では `-'、 追加行では `|' となり、変更されなかった行ではスペースとなる。 この形式では、改行が必要な部分には改行を入れて出力する。
      
 diff \
    --old-line-format='-%l
 ' \
    --new-line-format='|%l
 ' \
    --unchanged-line-format=' %l
 ' \
   old new

行形式を指定するには、以下のオプションのどれかを用いる。 FORMAT にはシェルのメタキャラクタが入っていることが多いので、 クォートするべきであろう。

--old-line-format=FORMAT
1 番目のファイルからの行だけを整形する。
--new-line-format=FORMAT
2 番目のファイルからの行だけを整形する。
--unchanged-line-format=FORMAT
両方のファイルに共通の行を整形する。
--line-format=FORMAT
全ての行を整形する。上記の全てのオプションを指定した場合に等しい。

行形式では、普通の文字はそれ自身を表す。変換指定は `%' で始まり、以下の形式をとる:

%l
行の内容を意味する。行末尾の改行はあっても含まない。 この形式では、行に改行があるかどうかは無視される。
%L
行の内容を意味する。行末尾の改行があればそれも含む。 行に改行がなければ、改行はないままになる。
%%
`%' を表す。
%c'C''
ここで C は文字 1 文字で、C を表す。 C にバックスラッシュやアポストロフィは指定できない。 例えば `%c':'' はコロンを表し、これは if-then-else 形式の then 部分でもコロンとして解釈される。通常はコロンは then 部分の終わりとして扱われる。
%c'\O''
ここで 0 は 1 桁から 3 桁までの 8 進数字であり、8 進のコード 0 に対応する文字を表す。例えば `%c'\0'' はナル文字になる。
Fn
ここで Fprintf(3) の変換指定で、 F により整形された行番号を表す。 例えば `%.5dN' は行番号を `%.5d' という書式で整形して表示する。 printf 変換指定の詳細は、上記の行グループ形式のサブセクションを見よ。

デフォルトの行形式は `%l' に改行文字を続けたものである。入力にタブ文字があり、 それが出力行の桁揃えに重要である場合には、`%l' や `%L' の行指定を タブストップの直後に置くとよい (すなわち `%l' や `%L' の前にタブ文字を置けばよい)。 あるいは -t オプションを用いるのもよいだろう。

行形式と行グループ形式を同時に用いると、様々な形式指定が可能となる。 例えば、以下のコマンドは diff の通常の形式と似た形式の指定である。 これを修正すれば、diff の出力を微調整することが可能になる。

 diff \
    --old-line-format='< %l
 ' \
    --new-line-format='> %l
 ' \
    --old-group-format='%df%(f=l?:,%dl)d%dE
 %<' \
    --new-group-format='%dea%dF%(F=L?:,%dL)
 %>' \
    --changed-group-format='%df%(f=l?:,%dl)c%dF%(F=L?:,%dL)
 %<---
 %>' \
    --unchanged-group-format='' \
    old new

ディレクトリの比較

diff への 2 つの引数がディレクトリだった場合、 両方のディレクトリにそれぞれのファイルが、 ファイル名のアルファベット順に比較される。 通常はファイルのペアに違いが全くなければ、何も出力しない。 しかし -s オプションを用いると、同一のファイルも報告する。 両方のディレクトリに同名のサブディレクトリがあると、 通常 diff は報告だけしてサブディレクトリ以下のファイルは比較しない。 しかし -r オプションを用いると、 ディレクトリツリーを辿れる限り、対応する全てのファイルを比較する。

片方のディレクトリだけにあるファイルに対しては、 diff は通常存在するファイルの内容を表示せず、 ファイルが片方にあって他方にはないことだけを報告する。 diff の振舞いを変えて、 他方のディレクトリにもファイルが空の状態で存在するかのように 動作させることもできる。すなわち diff は実際に存在するファイルの内容をすべて出力する。 (この出力は、ファイルが第 1 ディレクトリにあれば削除、 第 2 ディレクトリにあれば挿入となる。) この指定には -N オプションを使う。

古いほうのディレクトリに大きなファイルがあって、 新しいほうにはない場合、 -N オプションの代わりに -P オプションを用いるとパッチの大きさを小さくできる。 -P オプションは -N オプションと似ているが、第 2 ディレクトリにあるファイルの内容だけを 出力に挿入し、第 1 ディレクトリだけにあるファイルは無視する (すなわち、追加されたファイルだけを扱う)。 そして、パッチを当てる前に消去されたファイルを削除するよう、 パッチの先頭にパッチを当てるユーザーへの指示を書く。

ディレクトリの比較時に特定のファイルを無視させるには、 -x PATTERN オプションを用いる。シェルとは異なり、ファイル名の先頭のピリオドは、 パターン先頭のワイルドカードにマッチする。 シェルによって展開されないよう、 PATTERN はクォート記号で囲うべきである。 例えば `-x '*.[ao]'' は `.a' や `.o' で終わる名前のファイルをすべて無視する。 このオプションは、複数指定するとそれぞれが有効になる。 例えば `-x 'RCS' -x '*,v'' というオプションを指定すると、 ファイル名が `RCS' だったり `*,v' で終わるような ファイルとサブディレクトリをすべて無視する。

返り値

diff は以下の値のどれかで終了する:
0
全く変更がなかった。
1
変更があった。
2
何らかのエラーが起こった。

注意

プログラムのバグについては [email protected] へ報告してください。 ページの更新は Ragnar Hojland Espinosa <[email protected]> が行っています。