find:-execの引数がありません


206

今日はコマンドで助けられましたが、動作していないようです。これはコマンドです:

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 && rm {}\;

シェルが戻る

find: missing argument to `-exec'

基本的に私がやろうとしていることは、ディレクトリに再帰的に(他のディレクトリがある場合)実行し、.rmファイルタイプに対してffmpegコマンドを実行して、ファイルタイプに変換すること.mp3です。これが完了したら、.rm変換されたばかりのファイルを削除します。

私はこれについての助けに感謝します。

回答:


340

-execコマンドがで終了する必要があります;(あなたは通常タイプに必要なように、\;または';'シェルによって回避さinterpretionに)または+。違いは、を使用する;と、コマンドはファイルごとに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つのエラーがあります:

まず、を使用しますが、は独自のパラメータで{};ある;必要があります。

次に、コマンドはで終了します&&。「検索を実行し、それが成功した場合は、{};。という名前のファイルを削除します。」-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' - {} \;

しかし、もっと良い方法があります。サポートandとを見つけるorので、あなたはのようなことをするかもしれませんfind -name foo -or -name bar。しかし-exec、これはでも機能します。これは、コマンドが正常に終了した場合はtrue、そうでない場合はfalseと評価されます。この例を見てください:

$ ls
false  true
$ find * -exec {} \; -and -print
true

コマンドが正常に実行された場合にのみ印刷が実行さtruefalseます。

したがって、2つのexecステートメントをとチェーンして使用でき-and、前者が正常に実行された場合にのみ後者を実行します。


3
キーは、「私はそれ自身の引数です」というMarianの行のように思われます。ありがとう。
pjammer 2014年

3
これは、-execで読んだ最良の説明です。これは非常に強力ですが、適切な構文を取得するのは常に難しいと感じています。これにより、いくつかのことがより明確になりました。特に、コマンドを別のシェルでラップします。いいね。ありがとう。
Eurospoofer 2016年

3
-and-orポータブルではないことに注意してください。POSIXは-aおよびを指定し-o、実際に-aは常に想定されます(したがって必要ありません)。
gniourf_gniourf

また、ターミネータの前にスペースが必要です。Ex "\;"は機能しませんが、" \;"機能します
frmdstryr

56

私はそれを今理解した。execで2つのコマンドを実行する必要がある場合、実際には2つの別個のexecが必要です。これでようやくうまくいきました。

find . -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 \; -exec rm {} \;

削除するファイルの変数を取得するかどうか不明ですか?これが事実であるかどうか誰でも知っていますか?
Abs

7
そのようなことをテストするechoには、コマンドの前にを追加し、それが何をするかを見てください。
Marian

2
@Marian、echo非常に信頼性がない-あなたは違い言うことができないecho "one argument"echo one argument(それが実際に渡していて、後者の出力が偽であることをecho2つの完全に独立した引数)。-exec bash -c 'printf "%q " "$@"' _ ffmpeg -i {} -sameq {}.mp3 \; -printf '\n'DOSの改行やその他の奇妙さを検出できるように、印刷できない文字が見えるように出力を印刷するようなものを実行する方がはるかに優れています。
Charles Duffy

52

各\の前にスペースを入れてみてください。

作品:

find . -name "*.log" -exec echo {} \;

動作しません:

find . -name "*.log" -exec echo {}\;

1
これはかなり頻繁に私をつまずきます。ある日、デフォルトでスペースを追加します。
harperville 2015

私にとっては、Windows 7のCygwinとは正反対に機能します。スペース付きで動作します-動作しません。しかし、\を削除すると、前にスペースが付きます。動作し、前にスペースがありません。ここでは説明していません。
WebComer 2017

7

参考までに:
Cygwinシステム(WindowsでエミュレートされたUNIX)で「find -exec」コマンドを使用したところ、セミコロンの前のバックスラッシュを削除する必要があるようです:
find ./ -name "blabla" -exec wc -l {} ;


私は本当に混乱しました。find /etc/nginx -name '*.conf' -exec echo {} ;そして、find /etc/nginx -name '*.conf' -exec echo {}\;同じ結果を与えました。:(
カービー

私はWindowsのGitに付属しているBashシェルを実行しています。ダスティンカウルズの答えがうまくいきます。つまり、引用符なし、セミコロンでエスケープされたバックスラッシュ、後にスペース{}
mamacdon 2018年

意味に違いはありませんが、バックスラッシュを挿入する必要がある場合もあれば、挿入できない場合もあれば、選択する場合もあります。
ドミニク

2

Amazon Opsworks Chef bashスクリプトで同様の「欠落している-exec args」が見られる場合に備えて、\をエスケープするために別のバックスラッシュを追加する必要がありました。

bash 'remove_wars' do
  user 'ubuntu'
  cwd '/'
  code <<-EOH
    find /home/ubuntu/wars -type f -name "*.war" -exec rm {} \\;
  EOH
  ignore_failure true
end

2

また、他の誰かが「find:-execへの引数が不足しています」を持っている場合、これが役立つ可能性があります。

一部のシェルでは、エスケープを行う必要がありません。つまり、「;」の前に「\」を付ける必要はありません。

find <file path> -name "myFile.*" -exec rm - f {} ;

2
;引用されたか、ここではエスケープされていないこと、それはで読んでいない、シェルによって消費することができます意味しますfind。また、-fそして- f二つの異なるものです。
Charles Duffy

1

逃げる必要があると思います。

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} \-sameq {}.mp3 \&\& rm {}\;

0

{}と&&の両方は、コマンドラインによって展開されるため、問題を引き起こします。私は試してみることをお勧めします:

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i \{} -sameq \{}.mp3 \; -exec rm \{} \;

execの最初のコマンドが成功し、execの2番目のコマンドが実行された場合でも{}、正しいファイルを削除する変数にアクセスでき ますか?
Abs

Thinik {}は何に拡張しますか?2つのドットまたはコンマが含まれていない限り、そのままになります。
Marian

0

{}との間にスペースを入れる必要があります\;

したがって、コマンドは次のようになります。

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 && rm {} \;

-4

それでも "find:missing argument to -exec"が表示される場合は、execute引数を引用符で囲んでください。

find <file path> -type f -exec "chmod 664 {} \;"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.