我需要为*.py
放置在目录和所有子目录下的特定类型(例如)的所有文件计算md5校验摘要。
最好的方法是什么?
编辑:提出的解决方案非常好,但这并不是我所需要的。我正在寻找一种解决方案,以获取单个摘要校验和,该校验和将唯一标识整个目录-包括其所有子目录的内容。
我需要为*.py
放置在目录和所有子目录下的特定类型(例如)的所有文件计算md5校验摘要。
最好的方法是什么?
编辑:提出的解决方案非常好,但这并不是我所需要的。我正在寻找一种解决方案,以获取单个摘要校验和,该校验和将唯一标识整个目录-包括其所有子目录的内容。
Answers:
find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | awk '{print $1}' | sort | md5sum
find命令列出所有以.py结尾的文件。为每个.py文件计算md5sum。awk用于选择md5sums(忽略文件名,文件名可能不是唯一的)。md5sums被排序。然后返回此排序列表的md5sum。
我已经通过复制测试目录对此进行了测试:
rsync -a ~/pybin/ ~/pybin2/
我重命名了〜/ pybin2中的某些文件。
该find...md5sum
命令为两个目录返回相同的输出。
2bcf49a4d19ef9abd284311108d626f1 -
awk ...
如果您将布局视为签名的一部分,则@ValentinMilea仅删除该部分。
快速创建tar存档文件,并将其传输到md5sum
:
tar c dir | md5sum
这将产生一个md5sum,它对于您的文件和子目录设置应该是唯一的。没有在磁盘上创建文件。
ls -alR dir | md5sum
。最好不进行压缩,而只是读取。这是唯一的,因为内容包含文件的修改时间和大小;)
z
为gzip或j
bzip2添加。我都没做
tar
两次或在两台不同的计算机上复制相同的文件集会产生相同的准确结果。
ire_and_curses的使用建议tar c <dir>
存在一些问题:
rsync -a --delete
所做的工作是一致的:它几乎同步了所有内容(减去xattrs和acls),但是将根据所有者和组的ID同步,而不是基于字符串表示。因此,如果您同步到不一定具有相同用户/组的其他系统,则应将--numeric-owner
标志添加到tar只要没有解决第一个问题的方法(或者除非您确定它不会影响您),否则我不会使用这种方法。
find
上面提出的基于基础的解决方案也不是一件好事,因为它们仅包括文件,而不包括目录,如果校验和应牢记空目录,这将成为一个问题。
最后,大多数建议的解决方案并不是一致排序的,因为排序规则在系统之间可能有所不同。
这是我想出的解决方案:
dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum
关于此解决方案的注意事项:
LC_ALL=C
是为了确保整个系统的可靠排序顺序-print0
标志来解决此问题,find
但是由于这里还有其他问题,我只能看到使该命令变得更复杂而不值得的解决方案。PS:我的系统之一使用了一个有限的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
幸运的是,我没有名称中包含换行符的文件/目录,因此在该系统上这不是问题。
最适合我的解决方案:
find "$path" -type f -print0 | sort -z | xargs -r0 md5sum | md5sum
它对我最有效的原因:
其他答案的问题:
文件系统元数据不会因以下原因而被忽略:
tar c - "$path" | md5sum
不处理包含空格的文件名,也不检测文件是否已重命名:
find /path -type f | sort -u | xargs cat | 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)
我遇到了同样的问题,所以我想出了一个脚本,该脚本仅列出目录中文件的md5sum,如果找到子目录,它将再次从该目录运行,为此,脚本必须能够在当前目录中运行目录或子目录(如果在$ 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
如果您想真正独立于文件系统属性以及某些tar版本的位级差异,则可以使用cpio:
cpio -i -e theDirname | md5sum