我尝试通过一个命令中的 md5sum 比较两个文件夹中的所有文件。Debian 中的一些命令如下 (bash):
$ cd ~/FOLDER1
$ md5sum ~/FOLDER2/* | md5sum -c -
这个想法是,第一个 md5sum 的哈希输出将被传递到第二个 md5sum 中并用作输入文件。但是,测试表明它只是将 FOLDER2 中的每个文件与其自身进行比较并为每个文件返回“OK”。我认为这不起作用的原因是第一个 md5sum 输出的文件名包含完整路径。我查看了md5deep
但没有找到任何可以帮助我的东西。我知道可以对一个文件夹进行 md5sum,将结果写入文件,然后将该文件用作第二个 md5sum 的输入。我想通过管道在一行中完成所有操作,而不是使用两个命令并写出一个文件。
编辑:接受的答案这里(使用diff
)可能会做我想要的,但我不知道是否diff
(正确地)比较二进制文件。
编辑:为了使用 md5sum(显示文件名和“OK”)获取我想要的输出,我只能编写一个批处理文件。使用 执行diffFolders.sh ~/FOLDER1 ~/FOLDER2
。
#!/bin/bash
HERE=$PWD
cd "$1"
md5sum * > /tmp/md5sum.cmp
cd "$2"
md5sum -c /tmp/md5sum.cmp
cd $HERE
此脚本将仅比较 中存在的文件~/FOLDER
。如果~/FOLDER2
有其他文件,则不会比较这些文件,也不会有任何输出表明它们存在。
答案1
您可以使用流程替代将 2 个 md5sum 的输出传递给 diff。在这种情况下,diff 没问题,因为 md5 输出是纯文本。类似于:
diff <(md5 ~/FOLDER1/* | awk '{print $4}') <(md5 ~/FOLDER2/* | awk '{print $4}')
抱歉,我这里没有 Debian,所以无法在上面测试。以上内容是在具有 md5 的 OS X 上测试的,输出可能略有不同。在 OS X 上,md5 的第 4 列是实际的 md5 总和,这就是为什么我只取这些列。
除了 awk,您还可以使用cut
,但您可能需要更改分隔符以获取第 4 列(这些不是制表符分隔的)。
答案2
来自我的.bashrc 文件。
很古老的东西,应该可以编写更多排序代码。我从来没有时间重新编写它。(就像其他所有用于临时修复的东西一样,永远使用)我正在发布这段可耻的代码,希望有人可以做得更好并发布结果 :-)
特征 :
- 递归遍历
- md5sum 检查唯一性/差异
- 列出完整路径中的更新文件
代码说明了一切。arg1 是旧目录,arg2 是新目录。
function find-updated-files-between-old-new(){
[ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." > /dev/stderr && return 1;
( ( cat <(cd "$1";find . -type f -printf "+%p\n") <(cd "$2";find . -type f -printf "-%p\n")
)|sort -k1.2|tee 1>/dev/null >(uniq -us1|awk -v B="$2" 'BEGIN{sub("/$",""B)}/^-/{print B substr($0,3);
}') >(uniq -ds1|awk -vA="$1" -vB="$2" 'BEGIN{B=g(B);A=g(A)}{
C=substr($0,3);if(f(A)!=f(B))print B C;}function g(y){sub("/$","",y);return y}
function f(y,z,e){e="md5sum \""y""C"\"";e|getline z;close(e);return substr(z,1,32)}' )
) | cat
}
正如函数名称所暗示的
function find-files-name-collision-between-dir1dir2(){
[ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." > /dev/stderr && return 1;
( cat <(cd "$1";find . -type f -printf "+%p\n") <(cd "$2";find . -type f -printf "-%p\n") )|sort -k 1.2 | uniq -d -s 1
}
只是为了完整性
function mv-mergedir1todir2(){
[ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." && return 1;
( cd "$1" ; tar cf - . ) | (cd "$2" ; tar --keep-old-files xvf - )
echo -e "Done. Duplicate filnames are not replaced. \n#Use \n# ( cd \"$1\" ; tar cf - . ) | (cd \"$2\" ; tar --overwrite xvf - ) \n#if you do not like that. "
}
这段糟糕的代码应该从我的 bashrc 中删除,但是它已经存在很长时间了……
答案3
有点长,但如果匹配,则返回文件名和 OK。它不使用“-c”,而是仅比较在每个文件夹中的文件上运行 md5sum 后输出的两个字符串。
for f in *; do [[ -f $f ]] && if [ $(md5sum "$f" | cut -d" " -f1) == $(md5sum dir2/"$f" | cut -d" " -f1) ]; then echo "$f" "OK"; else echo "$f" "MODIFIED"; fi; done