UnixのForループ:サブディレクトリにファイルを含める

UnixのForループ:サブディレクトリにファイルを含める

Unixの単純なforループは次のとおりです。

for FILE in $BASE_WORK_DIR/*.pdf
   do
     echo $FILE
   done

.pdfこれにより、BASE_WORK_DIRディレクトリ内のすべてのファイルがエコーされます。

BASE_WORK_DIRPDFファイルも含むサブディレクトリがある場合はどうなりますか?

この場合、どの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リストを並べ替えるのではなく、一致するファイルがなくても文句を言わないでください。)しかし、アクセスできないディレクトリに関するエラーメッセージは表示されません。DoNN

答え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オプションが追加されました)findbash

ファイル名に改行文字が含まれていると問題が発生することに注意してください。

答え3

findファイル名の改行問題を解決する別の解決策:

find "$BASE_WORK_DIR" -name '*.pdf' -print0 |
  while IFS= read -d '' -r file;do
    # your magic here
  done

警告:これはZshとBashでのみ機能します。

-print0findGNUなどの一部の実装でのみ使用できますfind-exec printf '%s\0' {} +あなたの検索がそれをサポートしていない場合はそれを使用してください。

関連情報