我有一个充满文件的目录。每个文件都会被复制到特定类型的目标主机。
我想计算目录中每个文件的 MD5 总和,并将该 md5 总和存储在与生成总和的文件名匹配的文件中,但附加 .md5。
因此,举例来说,如果我有一个目录:
a.bin
b.bin
c.bin
最终结果应该是:
a.bin
a.bin.md5 # a.bin's calculated checksum
b.bin
b.bin.md5 # b.bin's calculated checksum
c.bin
c.bin.md5 # c.bin's calculated checksum
我已经尝试使用 find exec 和 xargs 进行此操作。
通过 find,我尝试了这个命令:
find . -type f -exec md5sum {} + > {}.md5
使用 xargs,我尝试了这个命令:
find . -type f | xargs -I {} md5sum {} > {}.md5
无论哪种情况,我最终都会得到一个名为 {}.txt 的文件,这并不是我真正想要的文件。
谁能指出如何调整这些来生成我想要生成的 md5 文件?
答案1
cd /path/to/files &&
for file in *; do
if [[ -f "$file" ]]; then
md5sum -- "$file" > "${file}.md5"
fi
done
答案2
重定向是shell的一个操作符。
在:
find some args > {}.md5
find
使用一些参数运行,其标准输出重定向到{}.md5
.
在这里,您需要find
启动一个 shell 来为每个文件执行一次重定向:
find . -type f -exec sh -c '
for file do
md5sum "$file" > "$file.md5"
done' sh {} +
如果您想避免该.md5
部分中的目录组件,您可以使用-execdir
许多实现支持的替代方案find
(尽管对于某些实现,您仍然会获得一个./
目录组件,而对于某些实现,即使使用以下命令,仍然会为每个文件运行一个 shell {} +
:
find . -type f -execdir sh -c '
for file do
md5sum "$file" > "$file.md5"
done' sh {} +
或者你可以这样做:
find . -type f -exec sh -c '
for file do
(cd "${file%/*" && exec md5sum -- "${file##*/}") > "$file.md5"
done' sh {} +
答案3
我知道通过管道传输到 while 循环会产生副作用,但我喜欢这个解决方案的简单性、可读性和可扩展性
find . -type f ! -name \*.md5 |\
while read a; do md5sum $a > $a.md5; done
要使用此 scipplet 来简单地检查总和:
find . -type f ! -name \*.md5 |\
while read a; do echo $a; md5sum -c $a.md5; done
答案4
cd /path/to/files && ls -1| xargs md5sum | xargs -l bash -c 'echo $0" "$1 > $1.md5'
第一个 xargs 生成,第二个 xargs 拾取并保存到 .md5
如果需要过滤文件模式,可以将 ls 替换为 find 或在后面添加 grep 。