web-dev-qa-db-ja.com

findを使用してスペースを含むファイル名のforループを実行する方法

私は次のスクリプトを持っています-それはfindを使用してファイル名をループすることになっていますが、ファイル名をスペースで分割するために継ぎ目がありますか?ファイル名をそのままにしておく必要があります

#!/bin/bash

for file in `find -name "*.avi"`
do
./myscript $file
done

誰か助けてもらえますか?

ありがとう

4
Rob
find -name "*.avi" -print0 | xargs -0 -n 1 echo

echoxargsする必要はありません。

find -name "*.avi" -print0 | xargs -0 -n 1 ./myscript
5
womble

また:find -name "*.avi" -exec ./myscript '{}' \;

Wombleの答えはほとんどの場合確実に機能しますが、Xargsはすべての実装のスペースで完全ではありません。 findの「exec」モードが壊れるのを見つけたことがありません。 Solarisはその点で特に気難しいものでした。

明らかに、「-print」は、forループ内のファイルのリストの出力を単純に生成するのに適しています。ただし、ファイルのリストに対してコマンドを実行している場合は、「-exec」オプションを実行する方が効率的です。

13
Magellan

再帰が必要ない場合:

#!/bin/bash

for file in *.avi
do
    ./myscript "$file"
done

変数を囲む引用符は必須であることに注意してください。

編集:

Kojiroが指摘しているように、再帰が必要でBash 4を使用している場合は、shopt -s globstarを追加し、globを**/*.aviに変更できます。

Xargsとfind-execに基づくソリューションに加えて、読み取り中にパイプするオプションもあります。これには、より古典的なループ方式でスクリプトを構造化できるという利点があります。それをあなたの例に当てはめてみましょう。

find -name "*.avi" | while read avifile; do
  ./myscript "$avifile"
done
1
andol