スペースを含むファイル名を検索するシェルの for ループ

スペースを含むファイル名を検索するシェルの for ループ

典型的な Microsoft Windows ファイル名を持つディレクトリを考えてみましょう。

新しいドキュメント.txt
Foo.doc
Foo - コピー.doc

各ファイルに対して次のような操作を行いたいと思います。

$(find ${POLLDIR} -type f -mmin +1 -print0) 内の sendfile について
する
  echo \"${sendfile}\"
  ls -l "${送信ファイル}"
  等々
  成功の場合
  それから
    mv "${sendfile}" "${donedir}/."
  フィ
終わり

引数として「${sendfile}」を使用して 1 つのコマンドを実行するだけでは十分ではないことに注意してください。エラー チェックやその他の処理 (成功時に「${sendfile}」を移動し、失敗時にログに記録するなど) を実行するためのループが必要です。

上記のコマンドのように、ファイル名を for 内で使用できるように、find からファイル名をエスケープ/引用符で囲むための「正しい」構成は何ですかls? 可能であれば、ファイル名を 1 つずつ temp ファイルに保存することは避けたいと思います。

find -printf '"%p"\n'私は、tripleeが質問のコメントで示唆したように、そうは思わない[ファイル名にスペースが含まれている場合、find をどのように使用すればよいですか?] は構造内で機能しますfor foo in $(...) do

この場合、 「不正な」文字を に置き換えるとうまくいくと思います?が、見た目が非常に悪くなります。 for ループは最終的に ${POLLDIR} 内のファイルを処理し、完了したらそれらを移動するので、「Foo bar.txt」が「Foo-bar.txt」と衝突する可能性は 0 (ほぼ) です。

これまでの私の最高の試みは次のとおりです。

$(${POLLDIR} を検索 -type f -mmin +1 -print | tr ' ' '?') の sendfile の場合
する
  ...
終わり

もっときれいなものを提案していただけますか?

答え1

使用find ... -print0 | while IFS="" read -d ""構文:

find "${POLLDIR}" -type f -mmin +1 -print0 | while IFS="" read -r -d "" sendfile
  do
    echo "${sendfile}"
    ls -l "${sendfile}"
    and-so-on
    if success_above
      then
        mv "${sendfile}" "${donedir}/."
    fi
done

-d ""、行末文字をヌル文字 ( \0) に設定します。これは、 で見つかった各ファイル名を区切るものでありfind ... -print0、 はIFS=""改行文字を含むファイル名でも機能するために必要です。POSIX によれば、スラッシュ ( /) とヌル文字 ( \0) のみが禁止されています。-rは、バックスラッシュが文字をエスケープしないことを保証します (そのため、\tたとえば は、tタブではなく、実際のバックスラッシュに一致します)。

関連情報