GNU/Linux >> Linux の 問題 >  >> Linux

スクリプトを再帰的に適用できるように、 `for FileIn`を`find`に変換しますか?

私は、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になるように宣言します。 その後、元のファイルを削除し、出力を元のビデオとまったく同じフォルダに保存する必要があります。

  1. これを再帰的に実行するように変換するにはどうすればよいですか? findを使用する場合 、変数$fileを宣言する場所 ?そして、どこで$targetを宣言する必要がありますか ?すべてfind 本当にワンライナー?私は本当にファイルを変数$fileに渡す必要があります 、条件チェックを実行する必要があるためです。

  2. そして、(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の入力になります ループ。

関連:CloudMagicはDropbox内のファイルの内容を検索できますか?

このコードをテストしている間、両方の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

Linux
  1. ターミナルに出没する8つの不気味なコマンド

  2. Linuxで特定のファイルを提供するパッケージを見つける方法

  3. Bashスクリプトをファイルに接続できますか?

  1. Bashスクリプトがエイリアスを認識しないのはなぜですか?

  2. $ pathにあるスクリプトの同じディレクトリの下にあるファイルを参照しますか?

  3. フォルダから最も古いファイルを削除するためのBashスクリプト?

  1. スクリプトから正しい終了コードを取得できませんか?

  2. シェルスクリプトで、閉じたファイル記述子の使用によって引き起こされるSigpipeを回避するにはどうすればよいですか?

  3. すべての端末出力をファイルに保存しますか?