我浏览了许多问题,但没有一个解决方案对我有用。我想对 cd [directory] 中指定的所有子目录中的所有文件运行 md5sum 检查。例子:
cd [directory]
for f in *; do
if [[ -f "$f" ]]; then
(md5sum -- "$f" > "md5_${f}")
fi
done
感谢评论者,我理解了我最初的错误,该错误将我的命令作为目录而不是运行它。
现在的问题是它在它正在查看的第一个目录中成功运行,但在子目录中无法正确运行。
每条评论
find . - type f ! - name /'md5_*' -execdir sh -c /
for f; do
b="$(basename "$f")";
[ ! -e "md5_$b" ] && md5sum "$b" > "md5$b"
done
输出 find: 路径必须先于表达式: - 用法: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path... ] [表达]
答案1
这可以通过一个命令来完成find
:
find . -type f ! -name 'md5_*' -execdir sh -c \
'for f; do
b="$(basename "$f")"
[ ! -e "md5_$b" ] || [ "$b" -nt "md5_$b" ] && md5sum "$b" > "md5_$b"
done' sh {} +
该! -name 'md5_*
选项排除 md5_* 文件,并且该-execdir
选项导致 find cd 到每个包含文件的目录,然后sh -c '....'
在其中运行命令。它sh -c ...
在每个目录中运行尽可能少的命令(通常只有一个,具体取决于系统上的最大命令行限制 - 目前通常为 2MB 或更多)。
[ ! -e "md5_$b" ] || [ "$b" -nt "md5_$b" ]
shell 脚本中的测试确保仅对文件不存在或文件比其文件新的md5sum
文件运行。md5_
md5_
如果你想md5sums.txt
每个目录中只有一个文件,那就更简单了:
find . -type f ! -name 'md5sums.txt' -execdir sh -c \
'md5sum "$@" >md5sums.txt' sh {} +
md5sums.txt
如果您只想要一个文件列出所有子目录中的所有文件,则更简单:
rm -f md5sums.txt
find . -type f -exec md5sum {} + >> md5sums.txt
这个版本应该与 busybox 的版本一起使用find
,也许还有其他简约版本:
find . -type f ! -name 'md5_*' -exec sh -c \
'for f; do
cd "$(dirname "$f")"
b="$(basename "$f")"
[ ! -e "md5_$b" ] || [ "$b" -nt "md5_$b" ] && md5sum "$b" > "md5_$b"
cd - >/dev/null
done' sh {} +
它的运行速度会慢一些,因为它必须在 shell 脚本中更改目录...并且它必须cd
对每个文件执行两次,而不是每个目录只执行一次。
我会使用pushd
和popd
来更改目录,但如果您正在运行 busybox find 或类似的程序,您可能也在运行sh
像dash
.
答案2
这将找到 a 中的所有文件/dir
并运行md5sum /dir/file
find /path/to/directory -type f -print0 | xargs -0I{} md5sum {}
答案3
这看起来像是一份工作find
:
find /directory -type f -exec sh -c 'a={}; md5sum -- $a > $a.md5' \;