今日はコマンドについて助けてもらったのですが、うまく動作していないようです。コマンドは次のとおりです。
find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 && rm {}\;
シェルが戻ってくる
find: missing argument to `-exec'
私が基本的にやろうとしているのは、ディレクトリを再帰的に調べて (他のディレクトリがある場合)、.rm
ファイル タイプに対して ffmpeg コマンドを実行し、それらをファイル タイプに変換することです.mp3
。これが完了したら、.rm
変換したばかりのファイルを削除します。
ベストアンサー1
コマンドは(したがって、通常はシェルによる解釈を避けるためにまたは を入力する必要があります)-exec
または で終了する必要があります。 の違いは、 の場合、コマンドはファイルごとに 1 回呼び出されますが、 の場合、すべてのファイル名に対して可能な限り少ない回数だけ(通常は 1 回ですが、コマンド ラインには最大長があるため、分割されることがあります)呼び出されることにあります。次の例を参照してください。;
\;
';'
+
;
+
$ cat /tmp/echoargs
#!/bin/sh
echo $1 - $2 - $3
$ find /tmp/foo -exec /tmp/echoargs {} \;
/tmp/foo - -
/tmp/foo/one - -
/tmp/foo/two - -
$ find /tmp/foo -exec /tmp/echoargs {} +
/tmp/foo - /tmp/foo/one - /tmp/foo/two
コマンドに 2 つのエラーがあります:
まず、 を使用します{};
が、 は;
独自のパラメータである必要があります。
次に、コマンドは で終わります&&
。「find を実行し、成功した場合は という名前のファイルを削除します{};
。」と指定しました。コマンドでシェルのものを使用する場合は-exec
、 のように、明示的にシェルで実行する必要があります-exec sh -c 'ffmpeg ... && rm'
。
ただし、bash コマンド内に {} を追加しないでください。特殊文字が含まれている場合に問題が発生します。代わりに、の後にシェルに追加のパラメータを渡すことができます-c command_string
(を参照man sh
)。
$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)
$
最初の例では、シェルによって評価されていることがわかります。次のようなファイルがあったと想像してください$(rm -rf /)
:-)
(補足: は-
不要ですが、コマンドの後の最初の変数は変数 に割り当てられます$0
。これは通常、実行されるプログラムの名前を含む特殊な変数であり、それをパラメータに設定するのは少し不潔ですが、ここではおそらく害はないので、それを に設定して から-
始めます$1
。)
つまり、コマンドは次のようになります
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
しかし、もっと良い方法があります。 find はand
と をサポートしているor
ので、 のようなことができますfind -name foo -or -name bar
。しかし、これは にも適用され-exec
、コマンドが正常に終了した場合は true に評価され、そうでない場合は false に評価されます。次の例を参照してください。
$ ls
false true
$ find * -exec {} \; -and -print
true
コマンドが成功した場合にのみ print が実行されます。これは の場合は実行されましたがtrue
、 の場合は実行されませんfalse
。
したがって、 で連鎖された 2 つの exec ステートメントを使用できます-and
。前者が正常に実行された場合にのみ後者が実行されます。