将 'diff' 与不匹配的目录和文件名一起使用

Using 'diff' with mismatched directories and filenames

我有两个独立的文件夹目录,其中大部分包含相同的文件,但两个文件夹的目录结构完全不同。文件名也不对应

因此,例如:

FOLDER 1
--- Subfolder A
    -file1
    -file2
--- Subfolder B
    -file3
    -file4

FOLDER 2
--- Subfolder C
    -Subfolder C1
        -file5
        -file6
        -file7
    -Subfolder C2
        -file8
        -file9

假设 file1=file5file2=file6file3=file7file4=file8file9是无与伦比的。

diff 命令是否有一些选项组合可以识别匹配项?使用 -r 执行递归 diff 似乎无法完成工作。

创建临时 Git 存储库。将第一个目录树添加到其中,然后提交。

删除所有文件并添加第二个目录树。进行第二次提交。

这两个提交之间的 git 差异将开启重命名检测,您可能会看到更有趣的内容。

这是一种获取 不同 and/or 相同 文件的方法 find and xargs:

find FOLDER1 -type f -print0 |
xargs -0 -I % find FOLDER2 -type f -exec diff -qs --from-file="%" '{}' \+

示例输出:

Files FOLDER1/SubfolderB/file3 and FOLDER2/SubfolderC/SubfolderC1/file5 differ
Files FOLDER1/SubfolderB/file3 and FOLDER2/SubfolderC/SubfolderC1/file7 are identical

因此,您可以使用 grep 过滤您想要的那些(参见示例)。

请注意,此解决方案支持嵌入空格和特殊字符(例如:换行符)的文件名,因此您不必担心

说明

对于 FOLDER1 (find FOLDER1 -type f -print0) 中的每个文件,执行:

find FOLDER2 -type f -exec diff -qs --from-file="%" '{}' \+

该行再次调用 find 以获取 FOLDER2 中的所有文件并执行以下(已处理):

diff -qs --from-file="<a file from FOLDER1>" <all the files from FOLDER2>

来自 man diff:

--from-file=FILE1
Compare FILE1 to all operands. FILE1 can be a directory.

例子

这是目录树和文件内容:

$ find FOLDER1 FOLDER2 -type f -exec sh -c 'echo "[=13=]": &&  cat "[=13=]"' '{}' \;
FOLDER1/SubfolderA/file1:
1=5
FOLDER1/SubfolderA/file2:
2=6
FOLDER1/SubfolderB/file3:
3=7
FOLDER1/SubfolderB/file4:
4=8
FOLDER2/SubfolderC/SubfolderC1/file5:
1=5
FOLDER2/SubfolderC/SubfolderC1/file6:
2=6
FOLDER2/SubfolderC/SubfolderC1/file7:
3=7
FOLDER2/SubfolderC/SubfolderC2/file8:
4=8
FOLDER2/SubfolderC/SubfolderC2/file9:
anything

这是获取 相同 的命令(管道):

$ find FOLDER1 -type f -print0 |
> xargs -0 -I % find FOLDER2 -type f -exec diff -qs --from-file="%" '{}' \+ |
> grep "identical$"
Files FOLDER1/SubfolderA/file1 and FOLDER2/SubfolderC/SubfolderC1/file5 are identical
Files FOLDER1/SubfolderA/file2 and FOLDER2/SubfolderC/SubfolderC1/file6 are identical
Files FOLDER1/SubfolderB/file3 and FOLDER2/SubfolderC/SubfolderC1/file7 are identical
Files FOLDER1/SubfolderB/file4 and FOLDER2/SubfolderC/SubfolderC2/file8 are identical

bashProcess Substitution and Arrays

的增强解决方案

如果您使用 bash,您可以先将所有 FOLDER2 文件名保存在一个数组中,以避免为 FOLDER1 中的每个文件调用 find

# first of all, we save all the FOLDER2 filenames (recursively) in an array
while read -d $'[=15=]' file; do
    folder2_files=("${folder2_files[@]}" "$file")
done < <(find FOLDER2 -type f -print0)
# now we compare each file in FOLDER1 with the files in the array
find FOLDER1 -type f -exec diff -qs --from-file='{}' "${folder2_files[@]}" \; |
grep "identical$"