是否有任何机器可读的输出用于比较两个目录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
亲自看看您可以从该输出中得到什么。
在这里,如果只是了解哪些文件在一个文件中,哪些文件不在另一个文件中,并且对于两者共有的文件,根据它们的类型决定如何比较它们,那么手动完成这两个任务并不困难。
例如,与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
,它们各自目录中的相对路径,那么它们的内容很可能不同。