ループが各プロセスが完了するのを待つように 'while'をより適切な関数に置き換えます。

ループが各プロセスが完了するのを待つように 'while'をより適切な関数に置き換えます。

複数のサブフォルダでファイルを再帰的に検索し、各ファイルを使用する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 -print0xargsまたは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

関連情報