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


18

次のコマンドを実行しようとしています:

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' +

これはエラーを返しています:

find: missing argument to -exec

このコマンドの何が問題なのかわかりません。マニュアルページと一致しているようです。

-execコマンド{} +

この-execオプションのバリアントは、選択されたファイルに対して指定されたコマンドを実行しますが、コマンドラインは、選択された各ファイル名を最後に追加することによって構築されます。コマンドの呼び出しの総数は、一致するファイルの数よりもはるかに少なくなります。コマンドラインは、xargsがコマンドラインを作成するのとほぼ同じ方法で作成されます。コマンド内では、「{}」のインスタンスは1つのみ許可されます。コマンドは開始ディレクトリで実行されます。

私も試しました:

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' '{}' +
find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar '{}' +
find a/folder b/folder \( -name *.c -o -name *.h \) -exec grep -I foobar '{}' +
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+

+最後にエスケープを試みましたか?find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
ジェイヘンドレン

3
古いバージョンのGNUを使用している可能性がありますfind。けれども-exec cmd {} +バリアントがPOSIXで、80年代以来利用されている、GNUは、それだけの(比較的)最近(2005年)を加え見つけます。何がfind --versionわかりますか?
ステファンシャゼル

2
@Koveras、それはその時でしょう。-exec {} +2005年の4.2.12に追加されました。古いGNUの発見では、(非POSIX)-print0 | xargs -r0を使用して同様のものを取得できます。4.11994
。-ステファンシャゼル

1
JRFergusonは、-nameパターン引数を引用する必要があることを(削除された回答で)指摘しました-name "*.c" -o -name "*.h"-execエラーとは無関係ですが、これは事実です。他のすべての回答ではワイルドカードが引用符で囲まれていますが、Gillesだけが言及しています。…(続き)
G-Manは「Reinstate Monica」と言います

1
(続き)…jlliagreの答えは、名前表現を-name "*.[ch]"説明なしに崩壊させます。これには、コマンドラインを簡素化し、具体的には、 -o。関係-oする式を見つけるのは難しいです。あなたのものは間違っています。エラーが発生しないようにコマンドが修正されている場合(Gillesの答えのように)、ファイルに対してgrepのみ実行され.hます。あなたがする必要があります'(' -name '*.c' -o -name '*.h' ')'
G-Manは「Reinstate Monica」と

回答:


18

周りで使用する単一引用符を削除する必要があります{}。コマンドは次のように簡略化できます。

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} +

旧式のGNU findバージョンを使用する場合でも、これは機能するはずです。

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} \;

おっと、それらはバッククォートではなく引用符であることを意図していた。
デビッドケネディ

{}シェルにとって特別な意味はないため、引用符は役に立ちません。
jlliagre

findのmanページから:「文字列 '{}'は、findの一部のバージョンのように、単独の引数だけでなく、コマンドの引数で発生するすべての場所で処理されている現在のファイル名に置き換えられます。構文は、シェルによる展開から保護するために、エスケープする必要があります( '\'を使用)。
デビッドケネディ

1
私は実際にマニュアルページでそれを読みましたが、事実、中括弧を引用する必要があることを知っているシェルはありません。どのシェルを使用していますか?
jlliagre

バッシュ。引用符の有無にかかわらず、とにかくエラーが発生します。
デビッドケネディ

10

「への引数がありません-exec」とは、通常、-への引数にexecターミネーターがないことを意味します。ターミネータは、文字のみを含む引数;(シェルコマンドで引用符で囲む必要があるため、通常は\;orで記述される';')、または{}and を含む2つの連続する引数である必要があり+ます。

ステファンChazelasは特定されていますが、サポートされていないのGNUのfindの古いバージョン使用していること-exec … {} +だけを-exec {} \;。GNUはの遅れた採用者でしたが-exec … {} +、アンティークの少ないツールスイート(Gitなどを含むCygwinなど)を入手することをお勧めします。 gitを欠いているが悪い従業員の試用をしていないGNUwin32 -to-use-linux-but-we-impose-windows vibe(Cygwinが提供します)。この機能は、9年以上前のバージョン4.2.12で追加されました(GNU findPOSIX準拠にするために最後に特定された機能でした)。

古いGNU findに固執したい場合は、-print0with xargs -0を使用して同様の機能を取得できます。グループ化されたコマンド実行、任意のファイル名のサポート。

find a/folder b/folder -name '*.c' -o -name '*.h' -print0 | xargs -0 grep -I foobar /dev/null

常にfindコマンドラインでワイルドカードを引用してください。それ以外の場合、次を含むディレクトリからこのコマンドを実行すると.cファイルすると、引用符で囲まれてい*.cないものが.c現在のディレクトリ内のファイルのリストに展開されます。

コマンドラインに追加/dev/nullすることは、1つの一致が見つかったgrep場合でも、grepが常にファイル名を出力するようにするための秘ensureですfind。GNU findでは、オプションを渡すことも別の方法です-H


1
cygwinが提供するbad-employee-trying-to-to-use-linux-but-we-impose-windowsバイブとはどういう意味ですか?
デビッドケネディ

GNUwin32は期待していません:(
デビッドケネディ

質問に対する私のコメントをご覧ください。
G-Manは「Reinstate Monica」と

セミを囲む引用符は、package.jsonスクリプト内から機能します。
bvj

2

次のようなコマンドが

find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar {} +

エラーを返します

find: missing argument to -exec

考えられる原因は古すぎるGNU findで、構文をサポートしていません-exec mycommand {} +。その場合-exec mycommand {} \;mycommand複数のターゲットを収集して実行する代わりに、検出されたターゲットごとに1回実行する低パフォーマンスの置換を実行しますmycommand 1回だけ。

ただし、GNU findは例えば

find . -type f -and -name "*.ttf" -exec cp {} ~/.fonts +

GNU find{} +、より一般的なのではなく、リテラルの組み合わせのみをサポートするため{} additional parameters +です。中括弧と+文字の間には何も挿入できないことに注意してください。これを試すと、同じエラーが表示されます:

find: missing argument to -exec

回避策は、機能する構文を使用{} additional parameters \;することですが、見つかったターゲットごとにコマンドを1回実行します。GNUでさらにパフォーマンスが必要な場合はfind、指定された引数に追加のパラメーターを追加できるラッパースクリプトを作成する必要があります。何かのようなもの

#!/bin/bash
exec mycommand "$@" additional parameters

十分に良いはずです。または、一時ファイルを作成したくない場合は、ワンライナーを使用して、次のようにパラメーターの順序を変更できます。

find . -type f -and -name "*.ttf" -exec bash -c 'mycommand "$@" extra arguments' {} +

実行しmycommand {list of ttf files} extra argumentsます。-cフラグの後にbashの特殊文字を二重エスケープする必要があることに注意してください。


(1)実際に質問に答える上記の部分は、すでに他の人によって与えられました。(2)あなたが説明しているのは、GNUの欠陥や欠陥ではなく、POSIXで指定されてfindいる正しい動作です。
G-Manは「Reinstate Monica」と

1
+1最後に、追加のパラメーターが機能しない理由に答える人!POSIX定義の欠陥のようです。
ジョナサン

GNU findを持っているなら、おそらくGNU を持っているでしょうcp。この場合、実行文字列の最後find ... -exec cp --target-directory ~/.fonts {} +に保持することができ{}ます。
ロアイマ

1

find . -type f -perm 0777 -exec chmod 644 {}\;

エラーが発生しました find: missing argument to ``-exec'

間にスペースを追加{}して\修正:

find . -type f -perm 0777 -print -exec chmod 644 {} \;


1
find手元の質問のコマンドにはそのような問題はありません。
クサラナナンダ

質問では、私が理解したことは問題ありませんが、問題は同じ「find: `` -exec 'への引数がありません」、問題は異なる-2の理由から発生する可能性があります、私は同じ問題文を見たので答えました。
シュリープール

@Kusalanandaの悲しみ、noobは報告されたエラーの解決策を提供しました。OPは質問のタイトルと本文の両方で述べています。
bvj

@bvjこの質問+は、の-execオプションの形式を明示的に扱っていますfind。この答えは、質問をしているユーザーが持っていない問題を修正しています。
クサラナンダ

-1

過去にexec構文に頭痛の種がありました。ほとんどの日、私はより良いbash構文を好む:

for f in `find a/folder b/folder -name "*.[ch]"`; do grep -I foobar $f; done

ファイルをグループとして扱いたい場合、それぞれが連続的に評価されるため、いくつかの制限がありますが、出力を他の場所にパイプすることができます


1
これは機能する傾向がありますが、名前に空白文字が含まれるファイルを正しく処理できないため、純粋検索バージョンよりも大幅に有用ではありません。
エタンライスナー

5
いいえ、これをしないでください。これは、ファイルにスペースやその他の「奇妙な」文字が含まれるとすぐに壊れます。また、これはより複雑で遅いfind … -exec … \;ため、ファイル名が手入れされていることがわかっていても、これを使用する理由はありません。
ジル 'SO-悪であるのをやめる'

これは、ファイル名に基づいて複数行のロジックを実行する必要がある状況(文字の削除、ディレクトリの作成、ファイルの移動など)に役立ちました。findで複数のことを1つexecにしようとするのは、これに費やしたかった5分間の頭痛の種でした。私のファイル名は飼いならされ、これで問題が解決しました:)
gMale
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.