diffコマンドについて
こんにちは、技術部のfuです。
今回は差分の確認を行うことができるコマンド、diffについて少し書いてみたいと思います。
なお、この記事の内容はCentOS 6.8でコマンドを実行し、その結果を記載しています。
まずは基本のファイル比較です。
以下のようなファイル、hogeとfugaがあったとします。
$ cat hoge ringo gorira rappa paseri
$ cat fuga gorira rakuda paseri ringo
変更元ファイル:hoge
変更先ファイル:fuga
として比較すると、
- 1行目のringoを削除
- 2行目(元ファイルは3行目)のrappaをrakudaに変更
- 4行目にringoを追加
このように変更が行われています。
これを色々なオプションをつけてdiffしてみました。
まず、オプションをつけずにファイルの比較を行いました。
$ diff hoge fuga 1d0 < ringo 3c2 < rappa --- > rakuda 4a4 > ringo
hogeと比較し、
- 削除されている部分は <
- 追加されている部分は >
といった形式で表示されます。
「rappa」→「rakuda」のように変更された箇所は、
- 「rappa」が削除された為、<
- 「rakuda」が追加された為、>
というような形となっています。
次に-uオプションをつけて比較を行いました。unified形式と呼ばれるようです。
$ diff -u hoge fuga --- hoge 2017-09-05 05:11:46.693565839 +0900 +++ fuga 2017-09-05 05:16:11.586791985 +0900 @@ -1,4 +1,4 @@ -ringo gorira -rappa +rakuda paseri +ringo
hogeと比較し、
- 削除されている部分は –
- 追加されている部分は +
といった形式で出力されます。
デフォルトでは変更箇所の前後3行が出力されますが、-U もしくは–unified=オプションを用いることにより、
前後の出力行数を変更することができます。但し、パッチとして利用する場合は少なくとも2行は必要なようです。
次に-cオプションをつけて比較を行いました。context形式と呼ばれるそうです。
$ diff -c hoge fuga *** hoge 2017-09-05 05:11:46.693565839 +0900 --- fuga 2017-09-05 05:16:11.586791985 +0900 *************** *** 1,4 **** - ringo gorira ! rappa paseri --- 1,4 ---- gorira ! rakuda paseri + ringo
hogeと比較し、
- 削除されている部分は –
- 追加されている部分は +
- 変更されている部分は !
といった形式で出力されます。
次に-yオプションをつけて比較を行いました。side-by-side形式と呼ばれるそうです。
$ diff -y hoge fuga ringo < gorira gorira rappa | rakuda paseri paseri > ringo
さらに–left-columnをつけると、変更点のみが右側に表示されるようになります。
-yオプションをつけないとオプションなしのdiffと結果が変わらないので注意が必要です。
$ diff -y --left-column hoge fuga ringo < gorira ( rappa | rakuda paseri ( > ringo
また、-W あるいは –width=オプションをつけることで、出力時の幅を指定することができます。デフォルトは130です。
$ diff -y --width=25 hoge fuga ringo < gorira gorira rappa | rakuda paseri paseri > ringo
左端から右端までの文字数の為、あまりに少ない数を指定すると以下のように途中で途切れてしまい、
わかりづらくなってしまうので、文字が途切れない程度に適度な幅を指定すると良いでしょう。
$ diff -y --width=10 hoge fuga ri < go go ra | ra pa pa > ri
細かい変更箇所まで知る必要はないが、ファイルに差異があるかどうかだけ知りたい。
そんな時は-qオプションをつけると、差異があるかどうかだけ教えてくれます。
$ diff -q hoge fuga ファイルhogeとfugaは違います
差異がない場合は何も返して来ません。
$ diff -q hoge piyo $
何か一言欲しい場合は-sオプションをつけると、差異がない場合でもメッセージを返してくれます。
$ diff -qs hoge piyo ファイルhogeとpiyoは同一
-sオプションだけだと、差異がない場合は上記メッセージが返されるだけですが、差異がある場合はオプションなしのdiffの結果が返されます。
$ diff -s hoge fuga 1d0 < ringo 3c2 < rappa --- > rakuda 4a4 > ringo
以上がファイルの比較ですが、diffコマンドではディレクトリ同士の比較を行うことも可能です。
test1, test2というディレクトリを作成し、test1にはhogeとfugaのコピーを、test2にはhogeのコピーのみを置きました。
ディレクトリ構造としてはこのような形で作成しています。
$ LANG=C tree . |-- fuga |-- hoge |-- test1 | |-- fuga | `-- hoge `-- test2 `-- hoge 2 directories, 5 files
2つのディレクトリを比較してみます。
$ diff test1/ test2/ test1/だけに発見: fuga
test2ディレクトリにはファイル「fuga」をコピーしなかった為、上記のような結果が出ました。
今度は「fuga」もtest2ディレクトリにコピーしてみます。
$ diff test1/ test2/ $
差異がなくなった為、何も出力されなくなりました。
-sオプションをつけると一つ一つ結果を教えてくれるようです。
$ diff -s test1/ test2/ ファイルtest1/fugaとtest2/fugaは同一 ファイルtest1/hogeとtest2/hogeは同一
次に、test2ディレクトリ内の「fuga」を変更してdiffを実行してみます。
$ diff test1/ test2/ diff test1/fuga test2/fuga 4a5 > gorira
オプションをつけずに実行すると、差異のあったファイルと変更箇所がそのまま出力されました。
細かい変更箇所は知る必要はないが差異があったことだけを知りたい場合は-qオプションをつけます。
$ diff -q test1/ test2/ ファイルtest1/fugaとtest2/fugaは違います
変更点のないファイルも出力したい場合はさらに-sオプションをつけます。
$ diff -sq test1/ test2/ ファイルtest1/fugaとtest2/fugaは違います ファイルtest1/hogeとtest2/hogeは同一
ここでふと、通常のファイルとディレクトリを比較するとどうなるのか気になって試してみました。
ファイル「hoge」と、test1ディレクトリを比較してみます。
$ diff hoge test1/ $ echo $? 0
エラーが出るかと想定して打ちましたが、返り値も「変更点がない」という意味の0です。
-sオプションをつけて再度実行してみました。
$ diff -s hoge test1/ ファイルhogeとtest1/hogeは同一
どうやら、test1ディレクトリ内のファイル「hoge」と比較していたようです。
比較先のディレクトリに比較元のファイルが存在しない場合は、当然エラーが返ってきます。
$ diff piyo test1/ diff: test1/piyo: そのようなファイルやディレクトリはありません
ちなみに、diffコマンドにおける返り値は、
- 0 だと「差異なし」
- 1 だと「差異あり」
- 2 だと「何らかのエラーが発生した」
となります。比較対象のファイルが存在しない場合などに2を返します。
余談ですが、日本語環境で–helpオプションを叩くと、
$ diff --help -------------------------------------------------------------------- -d --minimal できるだけがんばって、小さい差分を見つける。 --------------------------------------------------------------------
こんな記述がありました。なんだか和みますね。
但し、-dオプションは「より小さな差分を生成できる代わりに実行が遅くなる(非常に遅くなる場合もある)」ようなので、サイズの大きいファイルを比較する場合には注意が必要かもしれません。
CentOS標準のリポジトリで導入はできない為、詳細は割愛しますが[colordiff]という
diffの結果を色つきで出力できるコマンドも存在するようですので、興味がある方は導入してみるのもいいかもしれません。
とりとめのない内容の記事になってしまいましたが、今回はこれで失礼します。