Engineering Note

プログラミングなどの技術的なメモ

diffコマンドの使い方

console

Linux環境などでファイルやディレクトリ間の差分を確認する際にdiffコマンドというものが標準で用意されています。

今回はdiffコマンドの簡単な使い方をメモとして残していきます。

 

 

diffコマンドとは

diffコマンドはファイルやディレクトリの差分を表示するコマンドとして、1970年代のUNIX上で開発されたプログラムです。

 

最もシンプルな使い方は、コマンドの後に比較したいファイルを2つ渡してあげるだけです。

diff file1 file2

試しに上記コマンドで二つのファイルを比較してみます。

 

 $ diff sshd_config sshd_config.org
 15c15
 < Port 50050
 ---
 > #Port 22
 58c58
 < PasswordAuthentication yes
 ---
 > PasswordAuthentication no

 

上記はsshd_configの設定ファイルを比較したものとなり、実行結果として差分のある個所とその内容についてが表示されます。

まずどこで差分があるかを確認するために15c1558c58の部分に注目します。

最初の15という数字は範囲を示しており、ここでは15行目から15行目まで(つまり1行)で変更(change)があることを意味しています。

そのあとにどのような変更があるかを表示していて、<の部分は1つ目のファイルにだけある個所を、>の部分は2つ目のファイルにだけある個所を表示します。

このファイルではそれぞれPortPasswordAuthenticationの箇所がそれぞれ変更してあるので、そこの違いを表示してくれています

上記のcode>c以外にも以下のような変更種別があり、一目でどのような差分があるかを把握することができます。

 

  • <linenum1>c<linenum2>:変更
  • <linenum1>a<linenum2>:追加
  • <linenum1>d<linenum2>:削除

 

オプションの使い方

上記のシンプルな使い方に加え、オプションを渡すことが可能になっています。

diff [options] file1 file2

 

コンテキスト形式で出力する 

差分のある個所を文脈として前後も表示するオプションとしてコンテキスト形式があり、オプションとして-cを付与します。

 

 $ diff -c sshd_config sshd_config.org
 *** sshd_config 2020-08-23 11:14:16.493078500 +0900
 --- sshd_config.org     2020-04-23 15:43:27.677895955 +0900
 ***************
 *** 12,18 ****

   Include /etc/ssh/sshd_config.d/*.conf

 ! Port 50050
   #AddressFamily any
   #ListenAddress 0.0.0.0
   #ListenAddress :: 
 --- 12,18 ----

   Include /etc/ssh/sshd_config.d/*.conf

 ! #Port 22
   #AddressFamily any
   #ListenAddress 0.0.0.0
   #ListenAddress ::
 ***************
 *** 55,61 ****
   #IgnoreRhosts yes

   # To disable tunneled clear text passwords, change to no here!
 ! PasswordAuthentication yes
   #PermitEmptyPasswords no

   # Change to yes to enable challenge-response passwords (beware issues with
 --- 55,61 ----
   #IgnoreRhosts yes

   # To disable tunneled clear text passwords, change to no here!
 ! PasswordAuthentication no
   #PermitEmptyPasswords no

   # Change to yes to enable challenge-response passwords (beware issues with

 

ユニファイド形式で出力する

上記のコンテキスト形式では比較対象のファイルを別々に分けて出力しますが、ユニファイド形式では2つのファイルを合わせた状態で出力し、diffコマンド以外でもGitの差分出力でこの形式が利用されています。

ユニファイド形式で出力するには、オプションとして-uを付与します。

 

 $ diff -u sshd_config sshd_config.org
 --- sshd_config 2020-08-23 11:14:16.493078500 +0900
 +++ sshd_config.org     2020-04-23 15:43:27.677895955 +0900
 @@ -12,7 +12,7 @@

  Include /etc/ssh/sshd_config.d/*.conf

 -Port 50050
 +#Port 22
  #AddressFamily any
  #ListenAddress 0.0.0.0
  #ListenAddress ::
 @@ -55,7 +55,7 @@
  #IgnoreRhosts yes

  # To disable tunneled clear text passwords, change to no here!
 -PasswordAuthentication yes
 +PasswordAuthentication no
  #PermitEmptyPasswords no

  # Change to yes to enable challenge-response passwords (beware issues with

 

ユニファイド形式では、まず先頭2行で比較するファイルのタイムスタンプが出力されます。

@@ ... @@で囲まれた箇所は差分のあった個所を示しており、@@ -12,7 +12,7 @@の場合は、それぞれのファイルの12行目に変更があり、7行分表示します。

 

再帰的に差分を出力する

最後はディレクトリの内容を比較するために用いるオプションになります。

サブディレクトリ以下の階層を持つディレクトリの差分を確認する場合は、オプションとして-rを付与します。

 

 $ diff -r test1 test2
 diff -r test1/dir/dir1/test test2/dir/dir1/test
 1c1
 < test
 ---
 > hello

 

差分内容の詳細は表示せずに、差分があるか無いかだけを確認するには、オプションとして-rqを付与します。

 

 $ diff -rq test1 test2
 Files test1/dir/dir1/test and test2/dir/dir1/test differ

 

コマンド結果からdiffを確認する

チェックサムを確認する際に、予め入手したリストから対象のファイルのチェックサムを確認する場合は以下のように実行できます。

 

 $ diff <(md5sum sshd_config) <(grep sshd_config checksum)

 

参考書籍

新しいLinuxの教科書