Ich versuche den folgenden Befehl auszuführen:
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' +
Dies gibt einen Fehler zurück:
find: missing argument to -exec
Ich kann nicht sehen, was mit diesem Befehl nicht stimmt, da er mit der Manpage übereinstimmt:
-exec Befehl {} +
Diese Variante der Option -exec führt den angegebenen Befehl für die ausgewählten Dateien aus. Die Befehlszeile wird jedoch erstellt, indem jeder ausgewählte Dateiname am Ende angehängt wird. Die Gesamtzahl der Aufrufe des Befehls ist viel geringer als die Anzahl der übereinstimmenden Dateien. Die Befehlszeile ist in etwa so aufgebaut wie die Befehlszeilen von xargs. Innerhalb des Befehls ist nur eine Instanz von '{}' zulässig. Der Befehl wird im Startverzeichnis ausgeführt.
Ich habe auch versucht:
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 '{}' \+
+
am Ende der Flucht ?find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
find
. Obwohl die-exec cmd {} +
Variante POSIX ist und seit den 80er Jahren verfügbar ist, hat GNU find sie erst (relativ) vor kurzem (2005) hinzugefügt. Wasfind --version
sagt dir das?-exec {} +
wurde in 4.2.12 im Jahr 2005 hinzugefügt. In älteren GNU-Funden können Sie das (nicht-POSIX) verwenden-print0 | xargs -r0
, um etwas Ähnliches zu erhalten.4.1
ist von 1994.-name
Muster Argumente sollen zitiert werden:-name "*.c" -o -name "*.h"
. Dies ist wahr, obwohl es nichts mit dem-exec
Fehler zu tun hat. Sie werden feststellen, dass alle anderen Antworten die Platzhalter in Anführungszeichen setzen, obwohl nur Gilles dies erwähnt. … (Fortsetzung)-name "*.[ch]"
ohne Erklärung. Dies hat den Vorteil, dass die Befehlszeile vereinfacht und insbesondere die Befehlszeile entfernt wird-o
. Es-o
ist schwierig, Ausdrücke zu finden, die etwas betreffen . Dein ist falsch; Wenn Ihr Befehl so festgelegt ist, dass er nicht ausfällt (wie in Gilles 'Antwort), wird ergrep
nur für die.h
Dateien ausgeführt. Das musst du tun'(' -name '*.c' -o -name '*.h' ')'
.Antworten:
Sie müssen die einfachen Anführungszeichen entfernen, die Sie verwenden
{}
. Der Befehl kann wie folgt vereinfacht werden:Wenn Sie eine archaische GNU-Find-Version verwenden, sollte dies weiterhin funktionieren:
quelle
{}
für die Shell keine spezifische Bedeutung haben."Fehlendes Argument zu
-exec
" bedeutet normalerweise, dass dem Argument zu -exec
das Abschlusszeichen fehlt. Das Abschlusszeichen muss entweder ein Argument sein, das nur das Zeichen enthält;
(das in einem Shell-Befehl in Anführungszeichen gesetzt werden muss, damit es normalerweise geschrieben wird\;
oder';'
), oder zwei aufeinanderfolgende Argumente, die{}
und enthalten+
.Stephane Chazelas identifiziert , dass Sie eine ältere Version von GNU find verwenden , die nicht unterstützt
-exec … {} +
, nur-exec {} \;
. Obwohl GNU ein später Anwender von war-exec … {} +
, empfehle ich Ihnen eine weniger antike Tool-Suite (wie Cygwin , die Git und vieles mehr enthält, oder GNUwin32 , der Git fehlt, bei dem es aber keine schlechten Angestellten gibt) -zu-verwenden-Linux-aber-wir-auferlegen-Windows-Vibe, die Cygwin gibt). Diese Funktion wurde vor über 9 Jahren in Version 4.2.12 hinzugefügt (es war die letzte identifizierte Funktion, die GNUfind
POSIX-kompatibel gemacht hat).Wenn Sie sich an einen älteren GNU-Fund halten möchten, können Sie
-print0
mitxargs -0
eine ähnliche Funktionalität erhalten: gruppierte Befehlsausführung, die beliebige Dateinamen unterstützt.Zitieren Sie immer die Platzhalter in der
find
Befehlszeile. Andernfalls wird der Befehl ohne.c
Anführungszeichen*.c
in die Liste der.c
Dateien im aktuellen Verzeichnis aufgenommen , wenn Sie ihn in einem Verzeichnis ausführen, das Dateien enthält .Das Hinzufügen
/dev/null
zurgrep
Befehlszeile ist ein Trick, um sicherzustellen, dass grep immer den Dateinamen ausgibt, auch wennfind
zufällig eine einzelne Übereinstimmung gefunden wird. Bei GNU find besteht eine andere Methode darin, die Option zu übergeben-H
.quelle
Wenn ein Befehl wie
Gibt einen Fehler zurück
die wahrscheinliche Ursache ist zu altes GNU,
find
das keine Syntax unterstützt-exec mycommand {} +
. In diesem Fall muss ein leistungsarmer Ersatz ausgeführt-exec mycommand {} \;
werden, dermycommand
einmal für jedes gefundene Ziel ausgeführt wird, anstatt mehrere Ziele zu sammeln undmycommand
nur einmal auszuführen .GNU unterstützt
find
jedoch nicht zweil GNU
find
nur wörtliche Kombinationen{} +
statt allgemeinerer unterstützt{} additional parameters +
. Beachten Sie, dass sich zwischen den geschweiften Klammern und dem+
Zeichen nichts befinden darf . Wenn Sie dies versuchen, erhalten Sie den gleichen Fehler:Die Problemumgehung besteht darin, eine Syntax zu verwenden,
{} additional parameters \;
die funktioniert, den Befehl jedoch für jedes gefundene Ziel einmal ausführt. Wenn Sie mehr Leistung mit GNU benötigen, müssenfind
Sie ein Wrapper-Skript schreiben, das zusätzliche Parameter an die angegebenen Argumente anhängen kann. Etwas wiesollte gut genug sein. Wenn Sie keine temporäre Datei erstellen möchten, können Sie die Reihenfolge der Parameter wie folgt mithilfe eines Einzeilers ändern:
was ausgeführt wird
mycommand {list of ttf files} extra arguments
. Beachten Sie, dass Sie möglicherweise Sonderzeichen für die Bash nach dem-c
Flag doppelt maskieren müssen .quelle
find
, sondern das korrekte Verhalten, das von POSIX angegeben wird .find
Sie wahrscheinlich GNUcp
. In diesem Fall können Siefind ... -exec cp --target-directory ~/.fonts {} +
das{}
am Ende der Ausführungszeichenfolge behalten .find . -type f -perm 0777 -exec chmod 644 {}\;
habe Fehler
find: missing argument to ``-exec'
.Leerzeichen dazwischen einfügen
{}
und\
korrigieren:find . -type f -perm 0777 -print -exec chmod 644 {} \;
quelle
find
Befehl in der vorliegenden Frage enthält kein solches Problem .+
Form der-exec
Option zufind
. Diese Antwort behebt ein Problem, das der Benutzer, der die Frage stellt, nicht hat.Ich hatte in der Vergangenheit einige Kopfschmerzen mit der Exec-Syntax. An den meisten Tagen bevorzuge ich die schönere Bash-Syntax:
Es gibt einige Einschränkungen, wenn Sie die Dateien als Gruppe behandeln möchten, da jede Datei seriell ausgewertet wird. Sie können die Ausgabe jedoch auch an eine andere Stelle weiterleiten
quelle
find … -exec … \;
, sodass es keinen Grund gibt, dies zu verwenden, selbst wenn Sie wissen, dass Ihre Dateinamen zahm sind.exec
den 5 Minuten, die ich damit verbringen wollte, zu viel Kopfschmerzen. Meine Dateinamen waren zahm und das löste mein Problem :)