Unix 中一个简单的 for 循环是:
for FILE in $BASE_WORK_DIR/*.pdf
do
echo $FILE
done
这将回显.pdf
BASE_WORK_DIR 目录中的所有文件。
BASE_WORK_DIR
如果还包含子目录,其中也包含 pdf 文件怎么办?
在这种情况下,我如何设计我的 for 循环来获取所有 pdf 文件BASE_WORK_DIR
及其子目录BASE_WORK_DIR
?
答案1
标准、规范且可靠的语法是:
find . -type f -name '*.pdf' -exec sh -c '
for f do
something with "$f"
done' sh {} +
sh
(请注意,如果文件列表很大,它可能会运行多次调用)。
对于zsh
,等价于
for f (./**/*(.NDoN)) {
something with "$f"
}
(.
对于-type f
,D
包括隐藏文件,oN
不费心对列表进行排序,N
如果没有匹配的文件则不抱怨),但您不会收到有关您无权访问的目录的错误消息。
答案2
在 中bash4
,并且需要遵循目录的符号链接,您可以启用globstar
和使用**
:
shopt -s globstar
for file in "$base_work_dir"/**/*.pdf
do
echo "$file"
done
否则在sh
脚本中,find
可能是最好的方法:
IFS='
'
set -f
for file in $(find "$base_work_dir" -name *.pdf)
do
echo "$file"
done
(添加-L
选项以find
跟随符号链接,如bash
globstar)
请注意,如果任何文件名包含换行符,则会出现问题。
答案3
另一个解决方案find
可以解决文件名中的换行符问题:
find "$BASE_WORK_DIR" -name '*.pdf' -print0 |
while IFS= read -d '' -r file;do
# your magic here
done
买者自负:这只适用于 Zsh 和 Bash。
-print0
find
仅适用于GNU 等少数实现find
。-exec printf '%s\0' {} +
如果您的发现不支持它,请使用它。