文件夹是否有MD5(或类似文件)?如何验证两个文件夹是否相等?


10

我想找到md5sum一个文件夹(或类似的计算),而无需将其压缩到存档中。

例如,如果该文件夹中MyFolder,我们有文件1.txt2.txt3.txt包含:


1.txt

文字成1.txt

2.txt

文字成2.txt

3.txt

文字输入3.txt


我如何计算md5sum这整个MyFolder?有办法吗?我想用它来验证两个文件夹是否具有相同的内容。

这可以用来验证两个CD或文件夹是否相等。我想要一种简单的方法。

Answers:


15

md5deep工具是为正是为此目的而开发。许多Linux发行版都以软件包形式提供它。


1
谢谢!对我来说很好。对于其他有相同问题的用户来说,也是如此:非常 sudo apt-get install md5deep md5deep -rel /path/to/your/directory/ > directory_hash.md5 md5deep -X directory_hash.md5 -r /path/to/your/second/direcotory 感谢。
GarouDan 2011年

@GarouDan。您显示的命令将遵循符号链接。您可以使用该-o选项来处理文件类型。
Peter.O 2011年

哦...不知道...真的很有帮助。我会记得的!
GarouDan 2011年

4

如果您不想将其存档,则可以执行以下操作

diff <(find folder1) <(find folder2)

您可能需要调整find命令以使其更加准确。

编辑 您可以添加-exec到find调用中以比较文件的内容。类似于以下内容:

diff <(find folder1 -type f -exec md5sum {} \; | sort) <(find folder2 -type f -exec md5sum {} \; | sort)

请记住,您可能想对此进行调整。


这是一个有趣的观点。这列出了每个文件夹的所有文件...但是,如果我的存档量很大...如何验证每个文件夹中是否存在相同的文件(带有数据-可能使用md5sum工具)?
GarouDan 2011年

1
然后对每个文件的MD5SUM输出进行比较。您只需要以不同的方式将find,md5sum和diff命令串在一起。
sybreon,2011年

谢谢您的想法,谢谢。在感谢之后,我将尝试用这些有趣的东西找到这些命令。
GarouDan 2011年

3

一种测试方法是根据文件夹及其子文件夹中所有文件的串联生成md5sum。请记住,这还要求文件具有相同的名称(因为它们必须具有相同的排序顺序)。下面的代码应该工作:

#!/bin/bash

shopt -s nullglob
shopt -s globstar || { printf '%s\n' 'Bash 4 is required for globstar.' ; exit 1 ; }
(( $# == 2 )) || { printf '%s\n' "Usage: ${0##*/} olddir newdir" ; exit 2 ; }

for _file in "$1"/**/*; do [[ -f ${_file} && ! -L ${_file} ]] && _files_in_old_dir+=( "${_file}" ); done
for _file in "$2"/**/*; do [[ -f ${_file} && ! -L ${_file} ]] && _files_in_new_dir+=( "${_file}" ); done

(( ${#_files_in_old_dir[@]} )) || { printf '%s\n' 'No files in old dir.' ; exit 3 ; }
(( ${#_files_in_new_dir[@]} )) || { printf '%s\n' 'No files in new dir.' ; exit 4 ; }

_md5_old_dir=$(cat "${_files_in_old_dir[@]}" | md5sum)
_md5_new_dir=$(cat "${_files_in_new_dir[@]}" | md5sum)

{ [[ ${_md5_old_dir} == "${_md5_new_dir}" ]] && (( ${#_files_in_old_dir[@]} == ${#_files_in_new_dir[@]} )) ; } && printf '%s\n' 'Folders are identical.' || { printf '%s\n' 'Folders are not identical.' ; exit 3 ; }

如果您真正关心文件名等,则可以使用循环来比较${_files_in_old_dir}和中的内容${_files_in_new_dir}。这在大多数情况下都应该起作用(它至少检查目录及其子目录中的文件数)。


这是一个很好的脚本... thx @Chris。但这有一个问题...使用cat,子文件夹会因错误而崩溃...您有解决的办法吗?多谢。
GarouDan 2011年

这对我来说可以。确保您的外壳支持globstar。有什么错误?
克里斯·

1
它“有效”(+1)...,但是bash 4中的globstar遵循目录符号链接,但这仅是一个目录中包含符号链接的问题。
2011年

@fered好电话,我在测试中添加了。
克里斯·

0

我注意到原始帖子比较旧,但是,我认为这些信息对于那些正在寻找一种解决方案来验证文件是否正确复制的人仍然很有价值。Rsync可能是复制数据的最佳方法,此线程中给出的答案也不错,但是对于那些没有Linux经验的人,我将尝试给出更详细的解释。

场景:您只是将数据从磁盘复制到另一个磁盘,其中包含许多子目录和文件。您要验证是否正确复制了所有数据。

首先通过发出命令检查md5deep是否已安装md5deep -v

如果收到类似“找不到命令”之类的消息,请通过安装md5deep apt-get install md5deep

假设您只想处理常规文件。如果要处理其他类型的文件,请参考md5deep手册中的-o标志。(man md5deep

现在您可以使用了,我们假设您将文件从复制/mnt/orginal/mnt/backup,用这些文件替换您正在使用的任何目录。

首先更改到源目录,这是您复制或备份的文件的原始源:

cd /mnt/orginal

然后对每个文件进行校验和:

md5deep -rel -o f . >> /tmp/checksums.md5

该命令说明:

-r 启用递归模式

-e 显示进度指示器

-l 启用相对文件路径。

-o f 仅适用于常规文件(不适用于阻止设备,命名管道等)

. 告诉md5deep从当前目录开始。

>> /tmp/checksums.md5告诉md5deep将所有输出重定向到/tmp/checksums.md5

请注意,如果您要覆盖的早期版本中的内容/tmp/checksums.md5,请使用>和不>>

请注意,此命令可能需要花费相当长的时间,具体取决于io-speed和数据的大小。您可以尝试使用nice和/或ionice来提高md5deep的性能,但这超出了此答案的范围。

校验和的创建完成后,您现在将拥有一个文件,其中包含类似于以下内容的条目:

69c0a826b29c8f40b7ca5e56e53d7f83 ./oldconfig-11-09-2013/etc2/apm/event.d/20hdparm 651f3c7f79a14332f9fa7bb368039210 ./oldconfig-11-09-2013/etc2/apm/event.d/anacron 50d89784c1e201f68b-11b /etc2/apm/scripts.d/alsa e9b9131660a8013983bc5e19d7d669eb ./oldconfig-11-09-2013/etc2/ld.so.cache

第一列是md5校验和,第二列是校验和所属文件的相对路径。

如果要查看校验和文件中存在多少个文件,请发出以下命令:

wc /tmp/checksums.md5 -l

现在,您要检查复制的数据是否正确:

cd /mnt/backup

md5deep -o f -reX /tmp/checksums.md5 . >> /tmp/compare.result

与我们创建校验和时的唯一区别是-X,如果checksums.md5文件中的条目匹配,它将显示文件的当前哈希。因此,在测试结束时(如果/tmp/compare.result为空),由于校验和匹配,您可以相信所有文件都已正确复制。

请注意,仅/tmp/checksums.md5会检查文件中列出的文件的校验和是否正确,如果目录中还有其他文件,则/mnt/backupmd5deep不会将这些通知给您。

笔记:

  • 您不一定必须使用重定向来存储输出文件。有关更多信息,请参见md5deep手册。

  • 您可能必须以root用户身份运行md5deep命令,具体取决于要处理的文件的权限。


0

如果要递归检查两个目录之间的差异/path1/path2 而不使用md5deep

diff <(cd /path1 && find . -type f |xargs md5) <(cd /path2 && find . -type f |xargs md5)

说明:

  • 进入path1使所打印的所有行都find相对于path1cd /path1
  • 递归列出当前路径()中的所有文件&& find . -type f
  • 使用每行输出find作为md5| xargs md5)的输入

如果两者之间有任何差异,则输出将如下所示:

< MD5 (./index.html) = 36b01762f0329b2c12a5186520c7d78a
< MD5 (./inline.js) = ce99823a4b2c24839a727c5781f59a36
< MD5 (./main.js) = 3a597404d3ba7f0a6e3cb093ef57ebb2
---
> MD5 (./index.html) = 3a3d7663a7b2871ff37b9081a53593f9
> MD5 (./inline.js) = 1bbd0ecfc75b578413105c6b9009f9b3
> MD5 (./main.js) = 0f44abe5084add3cabdc39feec0c699878c78
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.