私は、bashスクリプトを実行していくつかの条件をチェックし、ffmpegを使用するという考えを持っています。 ディレクトリ内のすべてのビデオを任意の形式から.mkvに変換します そしてそれはうまく機能しています!
問題は、for file inを知らなかったということです ループは再帰的に機能しません(https://stackoverflow.com/questions/4638874/how-to-loop-through-a-directory-recursively)
しかし、私は「配管」をほとんど理解しておらず、例を見て、いくつかの不確実性を取り除くことを楽しみにしています。
私はこのシナリオを念頭に置いており、理解するのに大いに役立つと思います。
このbashスクリプトスニペットがあるとします:
for file in *.mkv *avi *mp4 *flv *ogg *mov; do
target="${file%.*}.mkv"
ffmpeg -i "$file" "$target" && rm -rf "$file"
done
現在のディレクトリで、*.mkv *avi *mp4 *flv *ogg *movを検索します。 次に、出力の拡張子が.mkvになるように宣言します。 その後、元のファイルを削除し、出力を元のビデオとまったく同じフォルダに保存する必要があります。
-
これを再帰的に実行するように変換するにはどうすればよいですか?
findを使用する場合 、変数$fileを宣言する場所 ?そして、どこで$targetを宣言する必要がありますか ?すべてfind本当にワンライナー?私は本当にファイルを変数$fileに渡す必要があります 、条件チェックを実行する必要があるためです。 -
そして、(1)が成功したと仮定して、「出力を元のビデオとまったく同じフォルダに保存する必要がある」という要件が満たされていることを確認するにはどうすればよいですか?
承認された回答:
あなたはこのコードを持っています:
for file in *.mkv *avi *mp4 *flv *ogg *mov; do target="${file%.*}.mkv" ffmpeg -i "$file" "$target" && rm -rf "$file" done
これは現在のディレクトリで実行されます。それを再帰的なプロセスに変えるには、いくつかの選択肢があります。最も簡単な(IMO)は、findを使用することです。 あなたが提案したように。 findの構文 は非常に「UNIXライクではない」ですが、ここでの原則は、各引数をANDまたはOR条件で適用できるということです。ここでは、「this-filenameが一致するかthat-filenameがThenprint-itと一致する場合」と言います。 「。ファイル名のパターンは、シェルがそれらを取得できないように引用符で囲まれています(引用符で囲まれていないパターンがすべてある場合は、シェルが引用符で囲まれていないすべてのパターンを拡張する必要があることに注意してください。*.mp4 そしてあなたはjaneeyre.mp4を持っていました 現在のディレクトリでは、シェルが*.mp4に置き換わります。 一致すると、find -name janeeyre.mp4が表示されます 目的の-name *.mp4の代わりに; *.mp4の場合、さらに悪化します 複数の名前に一致します…)。角かっこには\というプレフィックスが付いています また、シェルがサブシェルマーカーとしてそれらを実行しようとしないようにします(必要に応じて、代わりに角かっこを引用できます:'(' 。
find . \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' \) -print
この出力は、whileの入力に入力する必要があります 各ファイルを順番に処理するループ:
while IFS= read file ## IFS= prevents "read" stripping whitespace
do
target="${file%.*}.mkv"
ffmpeg -i "$file" "$target" && rm -rf "$file"
done
あとは、2つのパーツをパイプで結合するだけです| findの出力が whileの入力になります ループ。
このコードをテストしている間、両方のffmpegのプレフィックスを付けることをお勧めします およびrm echoを使用 だからあなたは何をするかを見ることができます 実行される–そしてどのパスで実行されるか。
echoを含む最終結果は次のとおりです。 テストに推奨するステートメント:
find . \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' \) -print |
while IFS= read file ## IFS= prevents "read" stripping whitespace
do
target="${file%.*}.mkv"
echo ffmpeg -i "$file" "$target" && echo rm -rf "$file"
done