Jak uruchomić find -exec?


Odpowiedzi:


710

Przegapiłeś ;(uciekłeś tutaj, \;aby powłoka go nie interpretowała) lub a +i a {}:

find . -exec grep chrome {} \;

lub

find . -exec grep chrome {} +

findwykona się grepi zastąpi {}znalezione nazwy plików. Różnica między ;i +polega na tym, że dla każdego pliku wykonywana jest ;jedna grepkomenda, podczas gdy dla +jak największej liczby plików podano jednocześnie parametry grep.


30
Jeśli używasz \; końcowy konstrukt grep jest przekazywany jeden plik na raz, więc domyślnie nie wyświetla nazwy pliku, tylko dopasowane linie. Aby zamiast tego uzyskać listę plików, dodaj użycie grep -lswewnątrz konstrukcji find.
Caleb

9
find . -exec grep foo {} +pokaże ci takie wyniki./dir/file.py:from foo import bar
sg

10
find . -exec grep foo {} \;pokaże ci takie wynikifrom foo import bar
sg

9
find . -exec grep -l foo {} +pokaże ci takie wyniki./dir/file.py
sg

8
find . -exec grep -l foo {} \;pokaże ci taki wynik./dir/file.py
sg

46

W ogóle nie musisz tego używać find; grep jest w stanie obsłużyć otwieranie plików z globalnej listy wszystkiego w bieżącym katalogu:

grep chrome *

... lub nawet rekurencyjnie dla folderu i wszystkiego pod nim:

grep chrome . -R

22
grep dusi się, jeśli rozszerzenie przekroczy ARG_MAX. -R odwiedzi wszystko podczas korzystania z funkcji znajdowania, można łatwiej dodawać prymitywy, aby wykluczyć niektóre pliki (-name itp.), A nawet nie odwiedzać poddrzewa (-prune).
Mel

6
Dobre punkty @Mel. Chodziło mi o to, że najprawdopodobniej strona pytająca sprawiła, że ​​sprawy były bardziej skomplikowane, niż trzeba, wprowadzając, findkiedy grepmożna wykonać zadanie, ale w niektórych przypadkach bardziej efektywne byłoby skorzystanie z funkcji znajdowania, aby dopracować listę plików przed wyjściem grep.
Caleb

4
@Mel grepw takim przypadku execnie dusi się .
Chris Down,

Działa tylko w przypadku, gdy wszystkie pliki znajdują się w tym samym katalogu, a nie gdy są one rozproszone w podkatalogach.
Yaba

1
@Yaba Moja odpowiedź mówi, jak obsługiwać przypadek plików rozproszonych w podkatalogach.
Caleb

18
find . | xargs grep 'chrome'

możesz także:

find . | xargs grep 'chrome' -ls

Pierwszy pokazuje linie w plikach, drugi po prostu wyświetla listę plików.

Opcja Caleba jest ładniejsza, mniej naciśnięć klawiszy.


11
Problem xargspolega na tym, że oczekuje, że jego dane wejściowe będą cytowane w szczególny sposób, findktóry nie daje rezultatów. Więc find … | xargs …nie działa, jeśli masz nazwy plików zawierające białe znaki lub \'".
Gilles,

3
@Gilles Możesz obejść ten problem, używając czegoś takiego find . | xargs -n1 -iX grep "X" 'chrome', aby argumenty były podawane pojedynczo i cytowane. Oczywiście jest to strasznie nieefektywny sposób radzenia sobie z tym przykładem, ale w niektórych sytuacjach jest to przyjemne.
Caleb

Dla kompletności powinniśmy również wspomnieć o opcji -i dla niewrażliwości na wielkość liter w 'grep'. Istnieje również -iname w znajdowaniu dla niewrażliwości na wielkość liter.
Mathew

9
@Caleb: Jedynym w 100% niezawodnym sposobem xargsradzenia sobie z nazwami plików w Linuksie jest find ... -print0 | xargs -0użycie NUL jako separatora. Alternatywa - xargs -d '\n'zastosowanie separatora nowej linii, 99% niezawodności.
grawitacja

Używam tego często, ale nie powiedzie się to na bardzo długich listach nazw plików, w którym to momencie find -exec staje się zwycięzcą.
Spacemoose

5

Znajdź to jeden ze sposobów i możesz spróbować, the_silver_searchera następnie wystarczy

ag chrome

Przeszukuje chrome we wszystkich plikach (włączając podkatalogi) i jest szybszy niż znajdź


Istnieje również pt (wyszukiwarka platyny, dostępna na github.com/monochromegane/the_platinum_searcher ), która, IMHO, wykonuje zadanie szybciej - może nie mieć znaczenia, jeśli jest tylko kilka plików.
Hopping Bunny


1

Oto przykład tego, jak zwykle używam find / exec ...

find  . -name "*.py" -print -exec fgrep hello {} \;

Wyszukuje rekurencyjnie wszystkie pliki .py, a dla każdego pliku drukuje nazwę pliku i fgrep dla 'witaj' w tym (dla każdego) pliku. Dane wyjściowe wyglądają (właśnie uruchomiłem dzisiaj):

./r1.py
./cgi-bin/tst1.py
print "hello"
./app/__init__.py
./app/views.py
./app/flask1.py
./run.py
./tst2.py
print "hello again"

1
aby nie zadzierać z przepływem pracy, ale możesz chcieć: find . -name "*.py" -exec fgrep -l hello {} \; - wypisze nazwy plików pasujących plików i nic więcej
Jeff Schaller
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.