Unixの単純なforループは次のとおりです。
for FILE in $BASE_WORK_DIR/*.pdf
do
echo $FILE
done
.pdf
これにより、BASE_WORK_DIRディレクトリ内のすべてのファイルがエコーされます。
BASE_WORK_DIR
PDFファイルも含むサブディレクトリがある場合はどうなりますか?
この場合、どのPDFファイルBASE_WORK_DIR
とそのサブディレクトリをインポートするようにforループをどのように設計できますか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
(globstarなどのシンボリックリンクに従う-L
オプションが追加されました)find
bash
ファイル名に改行文字が含まれていると問題が発生することに注意してください。
答え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' {} +
あなたの検索がそれをサポートしていない場合はそれを使用してください。