【 diff 】コマンド(応用編)――テキストファイルの差分を出力する:Linux基本コマンドTips(104)
本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は「diff」コマンドです。
本連載では、Linuxの基本的なコマンドについて、基本的な書式からオプション、具体的な実行例までを分かりやすく紹介していきます。今回はテキストファイルを比較して差分を出力する「diff」コマンドです。diffコマンドについては第102回(基本編)と、第103回(基本編その2)でも扱っています。
diffコマンドとは?
「diff」は、2つのテキストファイルを比較し、異なる箇所を出力するコマンドです。「diff ファイル1 ファイル2」と実行して、2つのテキストファイル(ファイル1、ファイル2)を比較します。ディレクトリ単位で比較することも可能です。
diffコマンドの主なオプション
diffコマンドのオプションを3種類に分けて紹介します。最初はコマンドの出力に関する主なオプションです。
短いオプション | 長いオプション | 意味 |
---|---|---|
-c | --context | 違いのある箇所をファイルごとに出力し、!記号で変更箇所を示す(context形式、第103回参照) |
-C 行数 | --context=行数 | context形式で出力する行数を指定(デフォルトは3行) |
-u | --unified | 違いのある箇所を1つにまとめて、-記号と+記号で変更箇所を示す(unified形式、第103回参照) |
-U 行数 | --unified=行数 | unified形式で出力する行数を指定(デフォルトは前後3行) |
-行数 | 異なっている部分の前後の行数を指定(-cまたは-u指定時) | |
-L ラベル | --label=ラベル | context形式とunified形式のヘッダに、ファイル名の代わりに出力するラベル(短縮形式「-L」は非推奨、第103回参照) |
-p | --show-c-function | 変更がC言語のどの関数で行われたのかを表示する。「-F'^[_a-zA-Z$]'」相当 |
-F 正規表現 | --show-function-line=正規表現 | context形式とunified形式で、各差分のブロックに対し、その前方がパターンにマッチした最後の行の一部を表示 |
-T | --initial-tab | normal形式やcontext形式で、テキストの前にスペースでなくタブを出力する(行中でのタブによる桁ぞろえが見やすくなる) |
-t | --expand-tabs | タブによる位置合わせを保存するため、出力のタブをスペースに展開する |
--inhibit-hunk-merge | 隣接する差分ブロックをマージしない | |
-D 名前 | --ifdef=名前 | if-then-else形式で出力する(“名前”はプリプロセッサの条件マクロで使用する名前) |
--changed-group-format=フォーマット | if-then-else形式で、両方のファイルで異なる行を出力する際のフォーマット | |
--line-format=フォーマット | if-then-else形式で、全ての入力行を出力する際のフォーマット | |
--new-group-format=フォーマット | if-then-else形式で、2番目のファイルだけにある行グループを出力する際のフォーマット | |
--new-line-format=フォーマット | if-then-else形式で、2番目のファイルだけにある行の出力に使用するフォーマット | |
--old-group-format=フォーマット | if-then-else形式で、1番目のファイルだけにある行グループを出力する際のフォーマット | |
--old-line-format=フォーマット | if-then-else形式で、1番目のファイルだけにある行の出力に使用するフォーマット | |
--unchanged-group-format=フォーマット | if-then-else形式で、両方のファイルに共通な行グループを出力する際のフォーマット | |
--unchanged-line-format=フォーマット | if-then-else形式で、両方のファイルに共通な行の出力に使用するフォーマット | |
-y | --side-by-side | 2列で出力する(side-by-side) |
-W 文字数 | --width=文字数 | side-by-side形式で出力する幅 |
--left-column | side-by-side形式で、共通な行は左側の列にのみ表示する | |
--suppress-common-lines | side-by-side形式で共通な行を表示しない | |
-e | --ed | edコマンドのスクリプト形式で出力する |
-n | --rcs | RCS(バージョン管理システム)形式の差分を出力する |
-l | --paginate | prコマンドによるページ付けを行う |
--strip-trailing-cr | 行末のCRを取り除く | |
-q | --brief | ファイルが違うかどうかだけを出力する |
-s | --report-identical-files | 2つのファイルが同じだったときも出力する |
diffコマンドの比較方法に関する主なオプションは次の通りです。
短いオプション | 長いオプション | 意味 |
---|---|---|
-i | --ignore-case | 大文字と小文字の違いを無視する |
-B | --ignore-blank-lines | 空行の有無を無視する |
-b | --ignore-space-change | スペースの数だけが異なる場合は違いを無視する |
-E | --ignore-tab-expansion | タブ展開によるスペースの変更を無視する |
-w | --ignore-all-space | 空白を無視して比較する |
-I 正規表現 | --ignore-matching-lines=正規表現 | パターンにマッチするような行を挿入・削除するだけの変更を無視する |
-H | --speed-large-files | 小さな変更が大量にあるような大きなファイルを高速に扱うためにヒューリスティックな手法を用いる(短縮形式「-H」は非推奨) |
-d | --minimal | より小さな差分を生成する(動作が遅くなる) |
--horizon-lines=行数 | 差分の前後にある共通部分を保持する行数 | |
-a | --text | ファイルを強制的にテキストと見なして1行ずつ比較する |
diffコマンドのディレクトリ比較に関する主なオプションは次の通りです。
短いオプション | 長いオプション | 意味 |
---|---|---|
-r | --recursive | ディレクトリを比較するとき、サブディレクトリも再帰的に比較する |
-S ファイル名 | --starting-file=ファイル名 | ディレクトリを比較する際の開始ファイル(中断した比較を続行する際に利用) |
--ignore-file-name-case | ファイルを比較する際に、ファイル名の大文字小文字を無視する | |
--no-ignore-file-name-case | ファイルを比較する際に、ファイル名の大文字小文字を考慮する | |
-N | --new-file | ディレクトリを比較する際、片方のディレクトリにのみファイルが存在していた場合、“新規ファイルとの比較”として動作する |
-P | --unidirectional-new-file | 2番目のディレクトリにのみファイルが存在していた場合のみ、新規ファイルとの比較として動作する(短縮形式「-P」は非推奨) |
-x パターン | --exclude=パターン | ディレクトリを比較する際に、除外するファイルを指定する |
-X リスト | --exclude-from=リスト | ディレクトリを比較する際に、無視する名前のパターンが書かれたファイルを読み込む |
ディレクトリ単位でファイルを比較する
「diff ディレクトリ1 ディレクトリ2」で、両方のディレクトリにある同名のファイル同士を比較します。サブディレクトリを再帰的に比較する場合は「-r」オプションを付けて実行します。
同名ファイルの内容に違いがあった場合、「diff ディレクトリ1/ファイル名 ディレクトリ2/ファイル名」と表示されて、比較の結果が出力されます(画面1)。
context形式やunified形式(変更箇所の前後も合わせて出力する形式、第103回参照)など、出力形式を指定するオプションは、そのまま使用できます(画面2)。
実行結果の読み方については、第102回と第103回を参照してください。
コマンド実行例
diff ディレクトリ1 ディレクトリ2
(ディレクトリ1とディレクトリ2内のファイルを比較する)(画面1)
diff -r ディレクトリ1 ディレクトリ2
(再帰的にサブディレクトリも比較する)
片方のディレクトリにしかないファイルを扱う
「diff ディレクトリ1 ディレクトリ2」と実行すると、両方のディレクトリ内にある同名のファイルを比較します。そのとき片方にしか存在しないファイルがあると、その旨表示されます(画面3)。
「-N」オプションを付けて実行すると、片方のディレクトリにしかないファイルと「(空の)新規ファイルとの比較」を実行した結果が出力されます(画面4)。ディレクトリ2にだけあるファイル(list3.csv)の場合、“全ての行を追加した”という表示になります。
コマンド実行例
diff -N ディレクトリ1 ディレクトリ2
(ディレクトリ同士を比較。片方にしかないファイルは空のファイルとの比較として出力する)(画面4、画面5)
変更があったファイルのリストを表示する
「-q」オプションを使うと、ファイルの内容を表示しないで、ファイルに違いがあるかどうかだけを出力できます。画面6ではnkfコマンド(ファイルの文字コードを変換するコマンド、連載第51回)のバージョン2.1.3と2.1.4のソースコードで、どのファイルに変更があったかを表示しています。なお、サブディレクトリ内も調べるため「-r」オプションを併用しています。
コマンド実行例
diff -q ディレクトリ1 ディレクトリ2
(ディレクトリ同士を比較し、違いがあるかどうかだけを出力する)(画面6)
筆者紹介
西村 めぐみ(にしむら めぐみ)
PC-9801NからのDOSユーザー(LinuxはPC-486DXから)。1992年より生産管理のパッケージソフトウェアの開発およびサポート業務を担当。のち退社し、ライターとして活動。著書に『図解でわかるLinux』『らぶらぶLinuxシリーズ』『はじめてでもわかるSQLとデータ設計』『シェルの基本テクニック』など。2011年より、地方自治体の在宅就業支援事業にてPC基礎およびMicrosoft Office関連の教材作成およびeラーニング指導を担当。
Copyright © ITmedia, Inc. All Rights Reserved.