我有两个目录具有相同的文件列表。我需要使用
diff
命令比较两个目录中存在的所有文件。是否有一个简单的命令行选项可以做到这一点,或者我是否必须编写一个 shell 脚本来获取文件列表,然后迭代它们?
您可以使用
diff
命令:
diff -bur folder1/ folder2/
这将输出一个忽略空格的递归差异,具有统一的上下文:
如果您只想查看不同的文件,您可以使用:
diff -qr dir_one dir_two | sort
选项“q”将仅显示不同的文件,但不显示不同的内容,“排序”将按字母顺序排列输出。
Diff 有一个选项
-r
就是为了做到这一点。
diff -r dir1 dir2
diff
不仅可以比较两个文件,还可以通过使用 -r
选项遍历整个目录树,递归检查每棵树中可比较点处出现的子目录和文件之间的差异。
$ man diff
...
-r --recursive
Recursively compare any subdirectories found.
...
另一个不错的选择是 über-diff-tool diffscope:
$ diffoscope a b
它还可以以 JSON、html、markdown 等形式发出差异
如果您特别不想比较文件内容,而只想检查两个目录中都不存在的文件内容,则可以比较由另一个命令生成的文件列表。
diff <(find DIR1 -printf '%P\n' | sort) <(find DIR2 -printf '%P\n' | sort) | grep '^[<>]'
-printf '%P\n'
告诉 find
不要在输出路径前加上根目录前缀。
我还添加了
sort
以确保两次调用 find
时文件的顺序相同。
末尾的
grep
删除有关相同输入行的信息。
当使用 git/svn 或磁盘上的多个 git/svn 实例时,这对我来说是过去 5-10 年中最有用的事情之一,有人可能会觉得有用:
diff -burN /path/to/directory1 /path/to/directory2 | grep +++
或:
git diff /path/to/directory1 | grep +++
它为您提供了所触及的不同文件的快照,而无需“减少”或“更多”输出。然后你只需比较各个文件即可。
如果它是 GNU diff 那么你应该能够将它指向两个目录并使用 -r 选项。
否则,请尝试使用
for i in $(\ls -d ./dir1/*); do diff ${i} dir2; done
注意正如丹尼斯在评论部分所指出的,您实际上不需要在 ls 上进行命令替换。我已经这样做了很长时间,以至于我几乎都是在自动驾驶仪上执行此操作并替换我需要获取文件列表以进行比较的命令。
我还忘记补充一点,我执行 '\ls' 来暂时禁用 ls 到 GNU ls 的别名,这样我就丢失了 GNU ls 返回的列表中的颜色格式信息。
在实践中,这个问题经常与一些限制一起出现。在这种情况下,以下解决方案模板可能会派上用场。
cd dir1
find . \( -name '*.txt' -o -iname '*.md' \) | xargs -i diff -u '{}' 'dir2/{}'
这是一个显示两个文件夹中文件之间差异的脚本。它递归地工作。更改 dir1 和 dir2。
(search() { for i in $1/*; do [ -f "$i" ] && (diff "$1/${i##*/}" "$2/${i##*/}" || echo "files: $1/${i##*/} $2/${i##*/}"); [ -d "$i" ] && search "$1/${i##*/}" "$2/${i##*/}"; done }; search "dir1" "dir2" )
上面的答案比这个更好,但我这样做是为了练习
bc -l <<< $(find dirname -type f -exec sum {} /tmp/{} \; | cut -f1 -d' ' | paste -d- - -) | grep -v 0