bash中find
是否懒惰?
我正在尝试浏览目录树,以使用以下脚本获取3级目录树中至少有700k文件的所有*.jpg
个文件:
for im in $(find $1 -name '*.jpg');
do
echo im;
# Do something with im...
done
但是没有从echo
打印任何内容就花了很长时间,我确信脚本可以工作(我使用3级目录树的50k文件测试它,它花费的时间更少但最后它打印了所有内容)。
也许有一个懒惰版本的find或者我可以用来让脚本运行时显示的echo
。
答案 0 :(得分:7)
$()
会立即分配所有find
的输出。使用while read
循环代替进程替换(推荐使用bash)或管道:
while IFS= read -r im; do
...
done < <(exec find "$1" -name '*.jpg')
exec
是我的风格,是可选的。因为我们只在进程替换召唤的子shell中运行一个命令,所以可能没有必要使用另一个fork。
或者
find "$1" -name '*.jpg' | while IFS= read -r im; do
# Unfortunately anything that happens here is already inside
# a subshell so any variable changes would not affect the
# parent shell.
...
done
如果你有不规则的文件名,比如文件名有换行符,请使用\x00
作为分隔符:
while IFS= read -r -d '' im; do
...
done < <(exec find "$1" -name '*.jpg' -print0)
如果循环中的一个命令读取输入,则需要使用另一个文件描述符来阻止这些命令从find
读取输入:
while IFS= read -ru 4 -d '' im; do
...
done 4< <(exec find "$1" -name '*.jpg' -print0)