diffはファイル同士の差分を表示するLinuxコマンドだ。
プログラムの更新時にどこを変更したかをリストするなど多くのシチュエーションで活躍する便利なコマンドだ。Linuxを扱うエンジニアであれば、使う機会が頻繁にあるだろう。
詳細を含めてdiffコマンドについてまとめてみた。コマンド実行例についてもすべてまとめているので、参考になるだろう。
コマンドの基本
コマンドの基本動作
使い方は、次のとおりコマンドの後に比較するファイル2つのファイルを指定するだけだ。
$ diff 比較するファイル1 比較するファイル2
例えば、workディレクトリ内の2つのファイル、test1.datとtest2.datの差異を表示する場合は、次のようになる。
$ diff work/test1.dat work/test2.dat
test1.datに対するtest2.datの差異が表示された。
結果に2c2と表示されているが、比較するファイル1の2行目が比較するファイル2の2行目に変更(c:Change)されているという意味だ。
その下に、差異のあった比較するファイル1の2行目の内容
---を挟んで、比較するファイル2の2行目の内容
が表示されている
上記diffコマンドを試すなら下のコマンドをLinux上で実行すればすぐに再現可能だ。
1 2 3 4 5 |
echo -e "ab\nc\nd" > work/test1.dat echo -e "ab\nc1\nd" > work/test2.dat cat work/test1.dat cat work/test2.dat diff work/test1.dat work/test2.dat |
差異が複数行の場合
差異が複数行の場合は、どのような表示なるか確認してみよう。
比較するファイル2の2行目と3行目の内容を書き換える。
$ echo -e "ab\nc1\nd1" > work/test2.dat
先ほどのdiffコマンドで同様に比較してみる。
$ diff work/test1.dat work/test2.dat
結果に2,3c2,3と表示されているが、比較するファイル1の2行目と3行目が比較するファイル2の2行目と3行目に変更(c:Change)されているという意味になる。
1 2 3 4 |
echo -e "ab\nc1\nd1" > work/test2.dat cat work/test1.dat cat work/test2.dat diff work/test1.dat work/test2.dat |
差異が離れた複数行の場合
差異が離れた複数行の場合は、どのような表示なるか確認してみよう。
比較するファイル2の1行目と3行目の内容を書き換える。
$ echo -e "ab1\nc\nd1" > work/test2.dat
先ほどのdiffコマンドで同様に比較してみる。
$ diff work/test1.dat work/test2.dat
結果が1c1と3c3の2つが表示された。比較するファイル1と比較するファイル2では、1行目同士、3行目同士が変更(c:Change)されているという意味だ。
1 2 3 4 |
echo -e "ab1\nc\nd1" > work/test2.dat cat work/test1.dat cat work/test2.dat diff work/test1.dat work/test2.dat |
削除された場合
行が削除された場合は、どのような表示なるか確認してみる。比較するファイル2を2行目がないものと置き換える。
$ echo -e "ab\nd" > work/test2.dat
先ほどのdiffコマンドで同様に比較してみる。
$ diff work/test1.dat work/test2.dat
結果が2d1と表示された。比較するファイル2では、比較するファイル1の2行目が削除(d:Delete)され、以降のテキストが1行の直後まで詰まったという意味だ。
1 2 3 4 |
echo -e "ab\nd" > work/test2.dat cat work/test1.dat cat work/test2.dat diff work/test1.dat work/test2.dat |
追加された場合
行が追加された場合は、どのような表示なるか確認してみよう。
比較するファイル2を3行目が追加されたものと置き換える。
$ echo -e "ab\nc\ne\nd" > work/test2.dat
先ほどのdiffコマンドで同様に比較してみる。
$ diff work/test1.dat work/test2.dat
結果が2a3と表示された。比較するファイル2では、比較するファイル1の2行目の直後に3行目が追加(a:Append)されているという意味だ。
1 2 3 4 |
echo -e "ab\nc\ne\nd " > work/test2.dat cat work/test1.dat cat work/test2.dat diff work/test1.dat work/test2.dat |
入れ替わっている場合
行が入れ替わった場合は、どのような表示なるか確認してみよう。比較するファイル2の2行目と3行目を入れ替えたものと置き換える。
$ echo -e "ab\nd\nc" > work/test2.dat
先ほどのdiffコマンドで同様に比較してみる。
$ diff work/test1.dat work/test2.dat
結果が2d1と3a3の2つが表示された。入れ替わりは、削除と追加で表現される。
1 2 3 4 |
echo -e "ab\nd\nc" > work/test2.dat cat work/test1.dat cat work/test2.dat diff work/test1.dat work/test2.dat |
変更がない場合
内容が同一で変更のない場合は、どのような表示なるか念のため、確認しておく。
比較するファイル2を比較するファイル1の内容と同一にする。
$ echo -e "ab\nc\nd" > work/test2.dat
先ほどのdiffコマンドで同様に比較してみる。
$ diff work/test1.dat work/test2.dat
変更がない場合、結果はなにも表示しない。
1 2 3 4 |
echo -e "ab\nc\nd " > work/test2.dat cat work/test1.dat cat work/test2.dat diff work/test1.dat work/test2.dat |
diffコマンドの便利なオプションたち
コマンドの一覧
後から詳細をご紹介するが、まずは一覧で確認しておく。
オプション -s
ファイルが異なるかのみチェックする
オプション -q
ファイルが異なるかのみチェックし同一の場合は結果を出力しない
オプション -c
結果をコンテキスト形式で表示する
オプション -C
差異のあった行から指定した行数をコンテキスト形式で表示する
オプション -u
結果をユニファイド形式で表示する
オプション -y
比較した結果を横並びで表示する
オプション -r
ディレクトリ同士で比較する
-sオプション:ファイルが異なるかのみチェックする
どこに差異があるかではなく、単純にファイルが同一のものかどうかを表示するオプションだ。
$ diff –s 比較するファイル1 比較するファイル2
workディレクトリ内の2つのファイル、test1.datとtest2.datの差異を同一かどうかのみ表示する場合は、次のコマンドになる。
$ diff –s work/test1.dat work/test2.dat
同一なので、同一と表示された。
1 |
diff –s work/test1.dat work/test2.dat |
-sオプションの差異があった場合の表示を確認しよう。比較するファイル2の2行目の内容を書き換える。
$ echo -e "ab\nc1\nd" > work/test2.dat
もう一度、先ほどと同様の-sオプションのコマンドで確認してみよう。
$ diff –s work/test1.dat work/test2.dat
異なる部分が差異として表示された。
1 2 |
echo -e "ab\nc1\nd" > work/test2.dat diff –s work/test1.dat work/test2.dat |
-qオプション:ファイルが異なるかのみチェックし同一の場合は結果を出力しない
-sオプションと同様、どこに差異があるかではなく、単純にファイルが同一のものかどうかを表示する。しかし、-qオプションは結果が同じ場合はなにも出力しないオプションだ。
$ diff –q 比較するファイル1 比較するファイル2
workディレクトリ内の2つのファイル、test1.datとtest2.datの差異を同一かどうかのみ表示する場合は、次のコマンドになる。
$ diff –q work/test1.dat work/test2.dat
異なると表示された。
1 |
diff –q work/test1.dat work/test2.dat |
-qオプションの差異がなかった場合の表示を確認しよう。
比較するファイル2を比較するファイル1の内容と同一にする。
$ echo -e "ab\nc\nd" > work/test2.dat
もう一度、先ほどと同様の-qオプションのコマンドで確認してみる。
$ diff –q work/test1.dat work/test2.dat
同一の場合はなにも表示しない。
1 2 |
echo -e "ab\nc\nd" > work/test2.dat diff –q work/test1.dat work/test2.dat |
-cオプション:結果をコンテキスト形式で表示する
結果をコンテキスト形式で表示するオプションだ。結果が同一の場合はなにも表示しない。
$ diff –c 比較するファイル1 比較するファイル2
workディレクトリ内の2つのファイル、test1.datとtest2.datの差異をコンテキスト形式で表示する場合は、次のコマンドだ。
$ diff –c work/test1.dat work/test2.dat
異なる部分がコンテキスト形式で表示された。
コンテキスト形式では、比較するファイル1と比較するファイル2のファイル名とタイムスタンプが表示され、差異のある行は変更された行から前後に数行表示される。差異のある行は「!」でわかるようになっている。
上記のオプションは次のコマンド一群でトライできる。
1 2 3 |
echo -e "ab\nc\nd\n12\n34\n56\n\n\n\n\n78\n9\nabc\nxyz\n" > work/test1.dat echo -e "ab\nc\nd3\n12\n34\n56\n\n\n\n\n78\n9s\nabc\nxyz\n" > work/test2.dat diff -c work/test1.dat work/test2.dat |
-Cオプション:結果をコンテキスト形式で表示する
-cオプション同様、結果をコンテキスト形式で表示するオプションだが、表示する行数を指定できる。結果が同一の場合はなにも表示しない。
$ diff –C 行数 比較するファイル1 比較するファイル2
workディレクトリ内の2つのファイル、test1.datとtest2.datの差異をコンテキスト形式で表示、差異のあった前後に2行表示する場合は、次のコマンドだ。
$ diff –C 2 work/test1.dat work/test2.dat
異なる部分が前後2行と共にコンテキスト形式で表示された。
diff -C 2 work/test1.dat work/test2.dat
-uオプション:結果をユニファイド形式で表示する
結果をユニファイド形式で表示するオプションだ。結果が同一の場合はなにも表示しない。
$ diff –u 比較するファイル1 比較するファイル2
workディレクトリ内の2つのファイル、test1.datとtest2.datの差異をユニファイド形式で表示する場合は、次のコマンドだ。
$ diff –u work/test1.dat work/test2.dat
異なる部分がユニファイド形式で表示された。
ユニファイド形式では、比較するファイル1と比較するファイル2のファイル名とタイムスタンプが表示され、変更という表現ではなく、差異のある行は追加が+、削除が-でわかるようになっている。
1 |
diff -c work/test1.dat work/test2.dat |
-yオプション:比較した結果を横並びで表示する
比較した結果を横並びで表示するオプションだ。結果が同一でも表示する。
$ diff –y 比較するファイル1 比較するファイル2
workディレクトリ内の2つのファイル、test1.datとtest2.datの比較結果を横並びで表示する場合は、次のコマンドだ。
$ diff –y work/test1.dat work/test2.dat
比較した結果が横並びで表示された。差異のある行は|でわかるようになっている。
diff -y work/test1.dat work/test2.dat
-rオプション:ディレクトリ同士で比較する
ディレクトリ同士で比較するオプションだ。
$ diff –r 比較するディレクトリ1 比較するディレクトリ2
workディレクトリ内のdata1ディレクトリとdata2ディレクトリの2つのディレクトリ内のファイル同士を順次比較する場合は、次のようになる。
$ diff –r work/data1/ work/data2/
比較の結果がオプションなしと同じ形式で表示される。片方にしか存在しないファイルは、片方にのみ存在と表示される。
上記のオプションは次のコマンドで演習できる。
1 2 3 4 5 6 7 8 |
mkdir work/data1 mkdir work/data2 echo -e "code:01\nname:apple\nname:price:130\n" > work/data1/apple.dat echo -e "code:01a\nname:apple\nname:price:140\n" > work/data2/apple.dat echo -e "code:02\nname:orange\nname:price:100\n" > work/data1/orange.dat echo -e "code:03\nname:grape\nname:price:300\n" > work/data1/grape.dat echo -e "code:03\nname:grape\nname:price:300\n" > work/data2/grape.dat diff –r work/data1/ work/data2/ |
複数のオプションを組み合わせる
複数のオプションを組み合わせると、視認性が飛躍的に向上する。
例えばworkディレクトリ内のdata1ディレクトリとdata2ディレクトリの2つのディレクトリ内のファイル同士を横並びで比較する場合は、次のようにする。
$ diff –ry work/data1/ work/data2/
ファイルごとに順次結果が横並びで表示される。
apple.datの差異のある部分に|が表示され、grape.datは差異がなかった。orange.datはdata1ディレクトリにしか存在しなかったという結果が、とてもわかりやすく表現された。
ちなみに-yオプションで-cや-uでの形式の変更オプションは同時には使えない。
関連項目
最後にdiffコマンドに関連して、基本的なファイル検索のコマンドも紹介しておく
find
ファイル名やディレクトリ名、更新日付などで検索する。
grep
ファイル内の文字を検索する。
echo
また、本文中でechoコマンドを使っているが、こちらのページを参考にして欲しい。
まとめ
diffコマンドを使ったファイルやディレクトリの比較の方法を解説してきた。
プログラミング中に自分で変更した点がわからなくなったとき、あらかじめバックアップしておいたファイルと比較することで、変更点を簡単に把握できる。
自分が作成したファイルを他人に改変してもらって、どこを変えてきたか、いちいち報告を受けなくてもこのコマンドを使えはすぐにわかる。
また、差分の結果をターミナルの画面上でコピーする操作やファイルへリダイレクトすることで変更履歴のドキュメントをすぐに作成でき、また、コンテキスト形式で保存しておけば外部の履歴管理ソフトなどでのバージョン管理の手続きもかなり効率化できる。
プログラマだけではなくHTMLおよびCSSのコーダーやデータベース管理者にとっても応用の範囲はかなり広いので、ぜひこの機会に操作方法を把握して欲しい。
コメント