Próbuję uruchomić następujące polecenie:
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' +
To zwraca błąd:
find: missing argument to -exec
Nie widzę, co jest nie tak z tym poleceniem, ponieważ wydaje się pasować do strony podręcznika:
-exec polecenie {} +
Ten wariant opcji -exec uruchamia określone polecenie na wybranych plikach, ale wiersz poleceń jest budowany przez dołączenie każdej wybranej nazwy pliku na końcu; całkowita liczba wywołań polecenia będzie znacznie mniejsza niż liczba dopasowanych plików. Linia poleceń jest budowana w taki sam sposób, jak xargs buduje swoje linie poleceń. W poleceniu dozwolona jest tylko jedna instancja „{}”. Polecenie jest wykonywane w katalogu startowym.
Próbowałem też:
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 '{}' \+
+
na końcu?find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
find
. Chociaż-exec cmd {} +
wariant jest POSIX i był dostępny od lat 80., GNU znalazł go (stosunkowo) dopiero niedawno (2005). Cofind --version
ci mówi-exec {} +
został dodany w 4.2.12 w 2005 r. W starszych znaleziskach GNU możesz użyć (nie POSIX),-print0 | xargs -r0
aby uzyskać coś podobnego.4.1
pochodzi z 1994 r.-name
argumenty wzorca powinny być podane:-name "*.c" -o -name "*.h"
. To prawda, chociaż nie ma to związku z-exec
błędem. Zauważysz, że wszystkie pozostałe odpowiedzi umieszczają symbole wieloznaczne w cudzysłowie, chociaż tylko Gilles o tym wspomina. … (Ciąg dalszy)-name "*.[ch]"
bez wyjaśnienia. Ma to tę zaletę, że upraszcza wiersz poleceń, a w szczególności eliminuje-o
. Znajdź wyrażenia wymagające-o
są trudne do znalezienia . Twoje jest złe; jeśli twoje polecenie zostanie naprawione, aby nie było błędu (jak w odpowiedzi Gillesa), będzie działaćgrep
tylko na.h
plikach. Musisz to zrobić'(' -name '*.c' -o -name '*.h' ')'
.Odpowiedzi:
Musisz usunąć pojedyncze cytaty, których używasz w pobliżu
{}
. Polecenie można uprościć w następujący sposób:Jeśli używasz archaicznej wersji GNU find, powinna ona nadal działać:
źródło
{}
nie miałyby żadnego konkretnego znaczenia dla powłoki.„Brak argumentu do
-exec
” zwykle oznacza, że argument do -exec
nie ma terminatora. Terminator musi być argumentem zawierającym tylko znak;
(który musi być cytowany w poleceniu powłoki, więc zwykle jest zapisany\;
lub';'
), lub dwoma kolejnymi argumentami zawierającymi{}
i+
.Stephane Chazelas stwierdził , że używasz starszej wersji GNU find, która nie obsługuje
-exec … {} +
, tylko-exec {} \;
. Chociaż GNU spóźnił się z przyjęciem-exec … {} +
, polecam, abyś dostał mniej zabytkowy zestaw narzędzi (taki jak Cygwin , który zawiera git i wiele więcej, lub GNUwin32 , który nie ma git, ale nie ma złych pracowników) -to-use-linux-but-we-impose-windows klimat, który daje Cygwin). Ta funkcja została dodana w wersji 4.2.12, ponad 9 lat temu (była to ostatnia zidentyfikowana funkcja, która pozwoliła uzyskaćfind
zgodność z GNU POSIX).Jeśli chcesz pozostać przy starszym znalezisku GNU, możesz użyć
-print0
z,xargs -0
aby uzyskać podobną funkcjonalność: grupowe wykonywanie poleceń, obsługa dowolnych nazw plików.Zawsze cytuj symbole wieloznaczne w
find
wierszu polecenia. W przeciwnym razie, jeśli zdarzy się, że uruchomisz to polecenie z katalogu zawierającego.c
pliki, niecytowany*.c
zostanie rozwinięty do listy.c
plików w bieżącym katalogu.Dodanie
/dev/null
dogrep
wiersza poleceń jest sztuczką, aby upewnić się, że grep zawsze wydrukuje nazwę pliku, nawet jeślifind
zdarzy się znalezienie pojedynczego dopasowania. W przypadku GNU find inną metodą jest przekazanie opcji-H
.źródło
Jeśli polecenie takie jak
zwraca błąd
prawdopodobną przyczyną jest zbyt stary GNU,
find
który nie obsługuje składni-exec mycommand {} +
. W takim przypadku należy uruchomić wymianę o niskiej wydajności,-exec mycommand {} \;
która uruchomi jedenmycommand
raz dla każdego znalezionego celu zamiast zbierać wiele celów i uruchamiaćmycommand
tylko raz.Jednak GNU
find
nie obsługuje npponieważ GNU
find
obsługuje tylko kombinację dosłowną{} +
zamiast bardziej ogólnej{} additional parameters +
. Zauważ, że między nawiasami klamrowymi a+
postacią nie może być niczego . Jeśli spróbujesz tego, otrzymasz ten sam błąd:Obejściem tego problemu jest użycie składni,
{} additional parameters \;
która działa, ale wykona polecenie raz dla każdego znalezionego celu. Jeśli potrzebujesz większej wydajności w GNUfind
, musisz napisać skrypt otoki, który może dołączyć dodatkowe parametry do podanych argumentów. Coś jakpowinno być wystarczająco dobre. Lub, jeśli nie chcesz tworzyć pliku tymczasowego, możesz użyć liniowania, aby zmienić kolejność parametrów w ten sposób:
który zostanie wykonany
mycommand {list of ttf files} extra arguments
. Pamiętaj, że może być konieczne dwukrotne ucieczkę znaków specjalnych do uderzenia za-c
flagą.źródło
find
, ale poprawnym zachowaniem określonym przez POSIX .find
, prawdopodobnie masz GNUcp
. W takim przypadku możeszfind ... -exec cp --target-directory ~/.fonts {} +
zachować{}
koniec na końcu łańcucha wykonawczego.find . -type f -perm 0777 -exec chmod 644 {}\;
dostał błąd
find: missing argument to ``-exec'
.Dodanie spacji
{}
i\
naprawiono:find . -type f -perm 0777 -print -exec chmod 644 {} \;
źródło
find
poleceniu w danym pytaniu nie ma takiego problemu .+
formy-exec
opcjifind
. Ta odpowiedź rozwiązuje problem, którego nie ma użytkownik zadający pytanie.W przeszłości miałem ból głowy ze składnią exec. przez większość dni wolę ładniejszą składnię bash:
Ma pewne ograniczenia, gdy chcesz traktować pliki jako grupę, ponieważ każdy jest oceniany szeregowo, ale możesz dobrze wyprowadzić wyniki gdzie indziej
źródło
find … -exec … \;
, więc nie ma powodu, aby z tego korzystać, nawet jeśli wiesz, że twoje nazwy plików są oswojone.exec
było zbyt wielkim bólem głowy przez 5 minut, które chciałem na to poświęcić. Moje nazwy plików były oswojone i to rozwiązało mój problem :)