「diff -r」の機械可読出力

「diff -r」の機械可読出力

2つのディレクトリを比較するために機械が読み取ることができる出力はありますかdiff

これにより、次のようなdiff -rq a b結果が得られます。

Only in a: aa
Only in b: bb
Files a/t and b/t differ

しかし、おそらく次のようなものをスクリプトで説明する方が簡単です。

- aa
+ bb
d t

ベストアンサー1

はい、diff -rq人が奇妙な名前のファイルに触れても、出力は後処理できません。たとえば、次を参照してください。

$ ls -lFA 1 2
1:
total 20
-rw-rw-r-- 1 chazelas chazelas 5 Aug 20 10:04  a
-rw-rw-r-- 1 chazelas chazelas 2 Aug 20 10:08 'A and B'
-rw-rw-r-- 1 chazelas chazelas 5 Aug 20 10:04 'a'$'\n''b'$'\n''Only in 1: foo'
lrwxrwxrwx 1 chazelas chazelas 4 Aug 20 10:10  lsock -> sock=
lrwxrwxrwx 1 chazelas chazelas 9 Aug 20 10:04  n -> /dev/null
srwxrwxr-x 1 chazelas chazelas 0 Aug 20 10:05  sock=
lrwxrwxrwx 1 chazelas chazelas 9 Aug 20 10:06  z -> /dev/zero

2:
total 14
-rw-rw-r-- 1 chazelas chazelas  5 Aug 20 10:04  a
-rw-rw-r-- 1 chazelas chazelas  2 Aug 20 10:08 'A and B'
lrwxrwxrwx 1 chazelas chazelas 17 Aug 20 10:09  lsock -> /run/udev/control=
lrwxrwxrwx 1 chazelas chazelas  9 Aug 20 10:05  n -> /dev/zero
lrwxrwxrwx 1 chazelas chazelas  9 Aug 20 10:10  sock -> ../1/sock=
lrwxrwxrwx 1 chazelas chazelas  9 Aug 20 10:05  z -> /dev/zero
$ diff -rq 1 2
Files 1/A and B and 2/A and B differ
Only in 1: a
b
Only in 1: foo
File 1/lsock is a socket while file 2/lsock is a socket
File 1/n is a character special file while file 2/n is a character special file

この出力から何が得られるかを直接確認してください。

ここでは、どのファイルが1つにあり、どのファイルが別のファイルにないのかを知り、両方のファイルに共通のファイルの種類に基づいて比較する方法を決定する場合、両方の操作を手動で実行することは難しくありません。

たとえば、次のようになりますzsh

zmodload zsh/stat
dirA=some/dir
dirB=some/other/dir
A_files=( $dirA/**/*(NDe['REPLY=${REPLY#$dirA/}']) )
B_files=( $dirB/**/*(NDe['REPLY=${REPLY#$dirB/}']) )

only_in_A=( ${A_files:|B_files} )
only_in_B=( ${B_files:|A_files} )
common_files=( ${A_files:*B_files} )
exact_same=()
different_type=()
different_content_regular=()
for file ($common_files) {
  stat -LsH a -- $dirA/$file && stat -LsH b -- $dirB/$file || continue
  if [[ $a[device]:$a[inode] = $b[device]:$b[inode] ]]; then
    exact_same+=( $file )
  elif [[ ${a[mode][1]} != ${b[mode][1]} ]]; then
    different_type+=( $file )
  elif [[ ${a[mode][1]} = - ]]; then
    (( a[size] == b[size] )) && cmd -s -- $dirA/$file $dirB/$file ||
      different_content_regular+=( $file )
  else
    : decide what to do with other types of files
  fi
}

(検証されていません)。

その後、さまざまな種類の違いに対して複数の配列を作成し、違いを計算して処理する方法を決定できます。たとえば、さまざまな方法でシンボリックリンクを処理できます。上記のコードで、およびが$dirA/foo同じ$dirB/fooシンボリックリンク(ハードリンクされている場合)の場合、上記のコードはそれをに追加しますが、そのディレクトリの相対パスを指す$exact_same場合はfile内容が異なる場合があります。

おすすめ記事