我如何可以计算出一个md5校验的一个目录?
题
我需要计算摘要md5校验和对所有特定类型的文件(*.py
例如)置于一个目录并且所有子目录。
什么是最好的方式做到这一点吗?
编辑: 所提出的解决方案是非常好的,但这不正是我所需要的。我在寻找一个解决方案,以获得一个 单摘要 校验,这将唯一确定的目录,作为一个整体,包括内容的所有其子目录。
解决方案
find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | awk '{print $1}' | sort | md5sum
查找命令列出了所有在的.py结尾的文件。 md5sum也计算每个.py文件。 AWK用于摘掉MD5SUMS(忽略文件名,这可能不是唯一的)。 与MD5SUMS进行排序。 然后此有序列表的的md5sum被返回。
我已经通过复制一个测试目录测试这样:
rsync -a ~/pybin/ ~/pybin2/
我改名的某些文件在〜/ pybin2。
在find...md5sum
命令返回两个目录相同的输出。
2bcf49a4d19ef9abd284311108d626f1 -
其他提示
即时创建和管,要md5sum
tar归档文件:
tar c dir | md5sum
这会产生一个单一的md5sum应该是唯一的,您的文件和子目录设置。没有文件被在磁盘上创建。
ire_and_curses的建议的使用 tar c <dir>
有一些问题:
- 焦油进程目录条目了它们储存在文件系统,和有没有办法改变这个秩序。这有效地可以产生完全不同的结果,如果你拥有"相同的"目录上不同的地方,我知道没有办法来解决这个问题(tar不能"排序"的输入文件在一个特定顺序)。
- 我通常关心是否组标识和所有人id数字是相同的,不一定是串的代表组/所有人都是一样的。这与例如什么
rsync -a --delete
不:它同步几乎所有(减xattrs和acl),但它将同步所有者和组根据他们的身份,而不串的代表性。所以如果你同步到一个不同的系统,这并不一定具有同样的用户/用户组,你应该加入--numeric-owner
标志焦油 - 焦油将包括文件的目录你检查本身,只是要知道的。
只要没有解决第一个问题(或除非你确定这不会影响你),我不会用这种方法。
的 find
基于解决方案的上述建议也没有好,因为他们仅包括文件、没有目录,这将成为一个问题如果你在校验和应牢记空的目录。
最后,大多数建议的解决方案不排序的一致,因为排序规则可能是不同的全系统。
这是解决我想出了:
dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum
注意到关于这个解决方案:
- 的
LC_ALL=C
为确保可靠的排序系统 - 这并不区分目录"命名
withanewline"和两个目录"命名为"和"withanewline",但本的机会,发生的历史似乎非常不可能的。一个通常修复这一点的
-print0
标志find
但是,由于没有其他的东西会在这里,我可以只看到的解决方案,将使该命令更为复杂,然后它的价值。
PS:我的一个系统的使用有限的很不错 find
不支持 -exec
也不 -print0
标志,也将'/'来表示的目录,而findutils找不到,所以用这个机我需要运行:
dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum
幸运的是,我没有文件的/目录内容的行在其名称,因此这不是一个问题,系统。
如果你只关心文件,而不是空目录,这很好地工作:
find /path -type f | sort -u | xargs cat | md5sum
有关完整起见,有 md5deep(1);它不能直接适用,由于*的.py过滤器的要求,但应与find做的罚款(1)一起。
一个解决方案,这最好的工作对我来说:
find "$path" -type f -print0 | sort -z | xargs -r0 md5sum | md5sum
为什么它的工作最好的对我说:
- 处理文件名称中包含空间
- 忽略文件系统元数据
- 检测,如果文件已重新命名为
问题与其他的答案:
文件系统元数据是不容忽视:
tar c - "$path" | md5sum
不处理文件名称中包含的空间,也没有检测,如果文件已经改名为:
find /path -type f | sort -u | xargs cat | md5sum
如果你想要一个跨越的md5sum整个目录,我会做类似
cat *.py | md5sum
校验所有文件,包括内容和它们的文件名
grep -ar -e . /your/dir | md5sum | cut -c-32
<强>与上述相同,但只包括* .py文件强>
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 /path -type f -name "*.py" -exec md5sum "{}" +;
从技术上讲,你只需要运行ls -lR *.py | md5sum
。除非你是担心有人修改文件,并接触他们回到原来的日期,永不改变文件的大小,从ls
输出应该告诉你,如果该文件已经修改。我的UNIX-foo是弱的,所以你可能需要一些更多的命令行参数,以获得创建时间和修改时间进行打印。 ls
还会告诉你,如果对文件的权限已经改变(我敢肯定,有开关把它们关掉,如果你不关心这个)。
我用HashCopy做到这一点。它可以生成和验证MD5和SHA上的一个文件或目录。它可以从www.jdxsoftware.org下载。
使用md5deep
:
md5deep -r FOLDER | awk '{print $1}' | sort | md5sum
我有同样的问题,所以我想出了这个脚本,仅列出文件的MD5SUMS在目录中,如果发现一个子目录从那里再次运行,要做到这一点的脚本必须能够运行通过当前的目录或子目录的,如果所述参数被传递在$ 1
#!/bin/bash
if [ -z "$1" ] ; then
# loop in current dir
ls | while read line; do
ecriv=`pwd`"/"$line
if [ -f $ecriv ] ; then
md5sum "$ecriv"
elif [ -d $ecriv ] ; then
sh myScript "$line" # call this script again
fi
done
else # if a directory is specified in argument $1
ls "$1" | while read line; do
ecriv=`pwd`"/$1/"$line
if [ -f $ecriv ] ; then
md5sum "$ecriv"
elif [ -d $ecriv ] ; then
sh myScript "$line"
fi
done
fi
如果你想真正从文件系统属性和一些焦油版本的有点水平的差异独立性,你可以使用的cpio:
cpio -i -e theDirname | md5sum
有两个解决方案:
创建:
du -csxb /path | md5sum > file
ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum > /tmp/file
检查:
du -csxb /path | md5sum -c file
ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum -c /tmp/file
md5sum
为我工作很好,但我曾与sort
和排序文件名的问题。于是我又通过md5sum
结果进行排序。我还需要排除以创建可比较的结果的一些文件。
find . -type f -print0 \
| xargs -r0 md5sum \
| grep -v ".env" \
| grep -v "vendor/autoload.php" \
| grep -v "vendor/composer/" \
| sort -d \
| md5sum