xargsで2つのパラメーターを一度に使用するにはどうすればよいですか?


18

ビデオを変換する必要がありますが、どこにあるのかわかりませんfind。どのように私はした結果、出力ファイル名を付けることができFFmpegのxargs

このコマンドを使用して2つのパラメーターを作成できることがすでにわかっています。

find . -iname "*.mov" -printf "%p %f\n"

xargsマニュアルに関連するものが見つかりません。私はこのようなものが欲しい:

find . -iname "*.mov" -printf "%p %f\n" | xargs ffmpeg -i {param1} -f flv {param2}

これどうやってするの?


xargs 一般的に複数の引数についての答えを探しているので、この質問に出くわした人はstackoverflow.com/questions/3770432/…をチェックアウトすることをお勧めします。
クリスオールド

回答:


4

このような何かがトリックを行い、フルパスを保持folder/movie.movfolder/movie.flv、スペースを処理し、名前をに変更します。

find . -name "*.mov" | while read movie;do
  ffmpeg -i "$movie" -f flv "${movie%.mov}.flv"
done

そして、私があなたを誤解していて、現在のディレクトリにすべての.flvムービーが必要な場合は、代わりにこれを使用してください。

find . -name "*.mov" | while read movie;do
  ffmpeg -i "$movie" -f flv "$(basename "${movie%.mov}.flv")"
done

3
ワンライナーとして使用する場合は、すべてを1行で入力してください。;)
マティアスアンバーグ

9

xargsユーザーがfindと組み合わせて使用する理由は、複数のファイル名が、起動するプログラムの同じプログラム呼び出しに渡されるためxargsです。たとえばfind、ファイルfoobar、およびbazを返す場合、次はmv1回だけ実行されます。

find sourceDir [...] -print0 | xargs -0 mv -t destDir

事実上、mv次のように呼び出します。

mv -t destDir foo bar baz

あなたが必要とするか(私はここにそうであると仮定して)この動作を望まない場合は、単に使用することができるfindのを-exec


この場合、簡単な解決策は、次のような短いシェルスクリプトを記述することです。

#!/usr/bin/env bash
[[ -f "$1" ]] || { echo "$1 not found" ; exit 1 ; }
P="$1"
F="$( basename $P )"
ffmpeg -i "$P" -f flv "$F"

名前を付けて保存しmyffmpeg.shて実行しchmod +x myffmpeg.shます。次に、次を実行します。

find . -iname "*.mov" -exec /path/to/myffmpeg.sh {} \;

これにより、見つかったファイルごとにシェルスクリプトが1回呼び出されます。シェルスクリプトは、フルパスからファイル名を抽出ffmpegし、適切な引数で呼び出します。


4

期待した解決策が得られなかったので、自分で解決策を見つけました。@Danielの答えは良いですが、シェルスクリプトが必要です。ライナーが1つである方が高速で、スクリプトを書くよりも簡単な解決策が好きです。

私は1つの引数を使用してそれを処理することができます basename、使用してsh -c

find . -iname "*.mov" -print0 | xargs -0 -i sh -c 'ffmpeg -i {} -f flv `basename {}`'

-iは{}、現在の引数に置き換えるようxargsに指示します。
``内のコマンド出力は標準出力(bash機能)に出力basename {}されるため、裸のファイル名として評価され、出力されます。
-0は特殊ファイル名を適切に処理するためのものですが、findで-print0オプションを使用してパラメーターを渡す必要があります


3

あなたはそこまでのすべての答えのようにそれをしなければなりませんが、xargsの正確な使用は次のようなものになります:

echo argument1 argument2 argument3 | xargs -l bash -c 'echo this is first:$0 second:$1 third:$2' | xargs

あなたの場合、それは次のようになります:

find . -iname "*.mov" -printf "%p %f\n" | xargs -l bash -c 'echo ffmpeg -i $0 -f flv $1' | xargs

PS:これはxargs、1つのxargsコマンドで複数のパラメーターの答えを正確に探している人のxargsに関する質問に答えます。


1

findコマンドの結果の形式に合わせてffmpegのオプションを単純に移動してみませんか?

find . -iname "*.mov" -printf "%p %f\n" | xargs -r -n2 ffmpeg -f flv -i

.movファイルが見つからない場合にffmpegを実行しないように、xargs-rオプションが追加されていることに注意してください。

-n2オプションをxargsに追加して、xargsが処理するアイテムの数を一度に2つに制限しました。この場合、項目はファイルパスとファイル名です。-nオプションが設定されていない場合、xargsは1回の実行でできるだけ多くの入力項目を処理します。


AFAICTで複数のファイルが見つかった場合、これは機能しません。
ダニエルベック

これは私にとっても一度しか機能しませんが、なぜそれが最初の後に停止するのか理解できません。何か案が ?
-kissgyorgy

実際には動作し
ません-kissgyorgy

Daniel-Beckと@Walkmanは、単一の実行については正しいです。この問題を解決するために、-n2オプションを使用して、xargsが一度に処理するアイテムの数を制限するようにこの回答を編集しました。-n2を指定しないと、xargsは、パイプを介して受け取る入力項目の数を処理できる場合に1回だけ実行されます。また、このソリューションは、ファイル名とファイルパスに空白が含まれていない場合にのみ機能することも指摘しておく必要があります。
ザスター

1

xargsを使用してそれを実行できるか、または実行する方法はわかりません。

しかし、このようなものはあなたのために働くはずです:

find . -iname "*.mov" -printf "%p %f\n" | while read -a HR ; do echo ffmpeg -i ${HR[0]} -f flv ${HR[1]} ;done

1
これは、ファイル名/パスのスペースを適切に処理しませんか?
ダニエルベック

1

ネームバインディングを使用したZoredacheの回答に代わる方法(およびファイル名のスペースの問題を回避するために異なるセパレータを使用):

IFS="\t" find -iname "*.mov" -printf "%p\t%f\n" | while read path file; do
    ffmpeg -i $path -f flv $file
done

もちろんfind -a array、他の回答が使用した引数とともにセパレータを使用することもできますが、名前付き引数の方がわかりやすい場合があります。


0

次のように、findコマンドからffmpegを直接実行できます。

find . -iname "*.mov" -exec ffmpeg -i "%p" -f flv "%f" \;

ファイル名にスペースが含まれている場合、ffmpegのパラメーターを囲む引用符に注意してください。エスケープされたセミコロンは、実行されたコマンドの終わりを示します。


printfフォーマットプレースホルダーも解釈する-execの動作に関するドキュメントはありますか?
ダニエルベック

いや。Brain fart:%pと%fはprintf-thingではなくfind-thingであると考えていました。あなたの答えに投票しました。
ランディオリソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.