我需要为一个特定类型的所有文件(*.py
例如)在一个目录及其所有子目录下计算摘要MD5校验和。
有什么最好的方法吗?
提供的解决方案很好,但这不完全是我需要的。我正在寻找一种解决方案,可以获得单个摘要校验和,该摘要校验和将唯一标识整个目录 - 包括其所有子目录的内容。
我需要为一个特定类型的所有文件(*.py
例如)在一个目录及其所有子目录下计算摘要MD5校验和。
有什么最好的方法吗?
提供的解决方案很好,但这不完全是我需要的。我正在寻找一种解决方案,可以获得单个摘要校验和,该摘要校验和将唯一标识整个目录 - 包括其所有子目录的内容。
在运行时创建一个tar归档文件并将其传输到md5sum
进行处理:
tar c dir | md5sum
这将生成一个MD5哈希值,应该对您的文件和子目录设置是唯一的。没有任何文件会被创建到磁盘上。
ls -alR dir | md5sum
。这样做甚至比压缩文件还要好,因为它只是读取文件而已。这条命令的独特之处在于内容包含了文件的修改时间和大小;) - Sidz
来使用 gzip,或者加上 j
来使用 bzip2。我两个都没加。 - ire_and_cursestar
同一组文件两次或在两台不同的计算机上进行操作,并不能保证会得到完全相同的结果。 - fletomfind /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | awk '{print $1}' | sort | md5sum
find 命令列出所有以 .py 结尾的文件。 对于每个 .py 文件,计算其 MD5 哈希值。使用 AWK 程序选择 MD5 哈希值(忽略可能不唯一的文件名)。 将 MD5 哈希值进行排序,并返回排序后的列表的 MD5 哈希值。
我通过复制测试目录进行了测试:
rsync -a ~/pybin/ ~/pybin2/
我重命名了~/pybin2中的一些文件。
find...md5sum
命令返回两个目录相同的输出结果。
2bcf49a4d19ef9abd284311108d626f1 -
为了考虑文件布局(路径),使得如果一个文件被重命名或移动,校验和也会改变,这个命令可以简化为:find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | md5sum
在 macOS 上使用 md5
:
find /path/to/dir/ -type f -name "*.py" -exec md5 {} + | md5
ire_and_curses提出的使用tar c <dir>
的建议有一些问题:
rsync -a --delete
所做的相一致:它会同步几乎所有内容(除了xattrs和acls),但会根据它们的ID而不是字符串表示来同步所有者和组。因此,如果您同步到一个不一定拥有相同用户/组的不同系统,应该在tar中添加--numeric-owner
标志。只要第一个问题没有解决方案(或者你确定它对你没有影响),我就不会使用这种方法。
提议的基于find
的解决方案也不好,因为它们只包括文件,而不包括目录,如果你想保留空目录,则会成为一个问题。
最后,大多数建议的解决方案在排序上不一致,因为在系统间可能存在不同的排序规则。
这是我想出来的解决方案:
dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum
关于这个解决方案的注意事项:
LC_ALL=C
用于确保不同系统之间具有可靠的排序顺序。find
命令中加上 -print0
标志来修复此问题,但由于这里还有其他事情需要处理,我只能看到会使命令变得更加复杂而不值得的解决方案。附注:我的一台机器使用了一个有限的 busybox find
,它不支持 -exec
和 -print0
标志,并且还会添加“/”来表示目录,而 findutils find 似乎没有这样做,因此对于这台机器,我需要运行:
dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum
幸运的是,我的文件/目录名称中没有换行符,因此在那个系统上这不是一个问题。$ mkdir a; touch a/file-1; touch a/file-2
$ mkdir b; touch b/file-2; touch b/file-1
$ (cd a; tar -c . | md5sum)
fb29e7af140aeea5a2647974f7cdec77 -
$ (cd b; tar -c . | md5sum)
a3a39358158a87059b9f111ccffa1023 -
- Dieter_befind“$dir”-type f-print0 | xargs -P 6-r0 md5sum | sort-k2
- motzmann如果你只关心文件而不是空目录,那么这个方法非常适用:
find /path -type f | sort -u | xargs cat | md5sum
cat
命令?它能处理文件名中带有空格的文件吗? - Peter Mortensensort -u
,但我们需要它,否则文件的顺序可能不同,因此校验和也会不同。 - Putnikfind /path -type f -print0 | sort -u -z | xargs --null cat | md5sum
命令来处理带有空格的文件名。 - Victor Klos对我最有效的解决方案:
find "$path" -type f -print0 | sort -z | xargs -r0 md5sum | md5sum
它对我而言最好的原因:
其他答案存在的问题:
对于以下操作,文件系统元数据没有被忽略:
tar c - "$path" | md5sum
不处理包含空格的文件名,也不检测文件是否已被重命名:
find /path -type f | sort -u | xargs cat | md5sum
find
命令的 -print0
选项。我们还有 xargs
命令的 -0
选项和 sort
命令的 -z
选项,它们会将空格替换为 null 字符。 - Tiago Lopo-print0
,-z
和--null
选项可以保持空格的完整性,而不会改变NULL字符的换行方式。 - Victor Klos为了完整起见,这里有md5deep(1);由于*.py过滤器的要求不直接适用,但与find(1)一起使用应该可以很好地完成。
cat *.py | md5sum
cat **.py
| md5sum 的命令 - Ramon对所有文件进行校验,包括内容和它们的文件名
grep -ar -e . /your/dir | md5sum | cut -c-32
grep -ar -e . --include="*.py" /your/dir | md5sum | cut -c-32
grep -aR -e . /your/dir | md5sum | cut -c-32
您可以考虑与grep一起使用的其他选项
-s, --no-messages suppress error messages
-D, --devices=ACTION how to handle devices, FIFOs and sockets;
-Z, --null print 0 byte after FILE name
-U, --binary do not strip CR characters at EOL (MSDOS/Windows)
GNU find
find /path -type f -name "*.py" -exec md5sum "{}" +;
ls -lR *.py | md5sum
。除非您担心有人修改文件并将它们触摸回原始日期并永远不更改文件大小,否则来自ls
的输出应告诉您文件是否已更改。我的unix-foo很弱,因此您可能需要一些更多的命令行参数才能打印出创建时间和修改时间。ls
还会告诉您文件权限是否已更改(如果您不关心权限,则我相信有开关可以关闭它)。