複数のサブフォルダでファイルを再帰的に検索し、各ファイルを使用するbashスクリプトがありますffmpeg
。デバッグに使用するとうまく機能しecho ffmpeg
ますが、問題は実際にffmpeg
使用し、各ビデオが完了するのを待つのに30分かかり、bashスクリプトがffmpeg
各ファイルに対して正常に実行されないことです。
私のスニペットは次のとおりです。
find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' ! -name '*-[900p].mkv' \) -print |
while IFS= read file ## IFS= prevents "read" stripping whitespace
do
ffmpeg -i "$file" "$target" && rm -rf "$file"
done
問題は、ffmpegが応答するのに時間がかかりすぎ、引き続きwhile
リストして実行するためです。もしそうなら、ループがdone
終わった後にのみループが処理されるようにする方法があります。
誰でも助けることができますか?ありがとうございます!
OMG、なぜ私は他の質問と重複する可能性があるのかがわかりません。スクリプトが再帰的に適用されるように、「for file in」を「find」に変換します。
次のオブジェクトを繰り返す前に、ループ内の各関数が完了するまでbashスクリプトが待機できるようにするループ操作を要求します。これは、再帰的に保管する方法を尋ねるのとは離れていますfind
。ありがとうございます!
答え1
findをループにパイプする代わりに、中間ファイルを繰り返すことができます。これにより、検索フェーズとループフェーズが順次発生し、重なり合うことがなくなります。次のようになります(簡潔に表現を変更しました)。
find \( -name '*.mkv' -o -name '*avi' \) >files
<files while IFS= read file
do
ffmpeg -i "$file" "$target" && rm -f "$file"
done
これはまだ完全に安全ではありません。find -exec
要件にfind
最初の呼び出しの前に厳密に実行することが含まれていない場合は、使用する方が簡単ですffmpeg
。この要件に応じて、find -print0
xargsまたはGNUパラレルを使用すると、アクションが実行されます。
答え2
コードが正しく機能しないのは、find
初期コマンドのANDグループとORグループが一致しないためです。
find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' ! -name '*-[900p-by-ZiriusPH].mkv' \) -print
パラメータバインディングは、一致するファイルを印刷することです。
- 名前*.mkv
- または名前*.avi
- または名前* mp4
- または名前* flv
- または名前*.ogg
- または名前*.ogg
- または(名前*.movと名前ではありません*-[900p-by-ZiriusPH].mkv)
最後の条件は多くのファイルに適用されますが、これはあなたが望むものではないと思います。 AND NOT 条件を角かっこで囲まれた OR 条件から移動すると、期待どおりに動作することを確認できます。
find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' \) ! -name '*-[900p-by-ZiriusPH].mkv' -print