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.
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 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.
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.
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):
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
find: Only one instance of {} is supported with -exec ... +
-exec
zfind
Odpowiedzi:
Przegapiłeś
;
(uciekłeś tutaj,\;
aby powłoka go nie interpretowała) lub a+
i a{}
:lub
find
wykona sięgrep
i zastąpi{}
znalezione nazwy plików. Różnica między;
i+
polega na tym, że dla każdego pliku wykonywana jest;
jednagrep
komenda, podczas gdy dla+
jak największej liczby plików podano jednocześnie parametrygrep
.źródło
grep -ls
wewnątrz konstrukcji find.find . -exec grep foo {} +
pokaże ci takie wyniki./dir/file.py:from foo import bar
find . -exec grep foo {} \;
pokaże ci takie wynikifrom foo import bar
find . -exec grep -l foo {} +
pokaże ci takie wyniki./dir/file.py
find . -exec grep -l foo {} \;
pokaże ci taki wynik./dir/file.py
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:... lub nawet rekurencyjnie dla folderu i wszystkiego pod nim:
źródło
find
kiedygrep
moż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.grep
w takim przypadkuexec
nie dusi się .możesz także:
Pierwszy pokazuje linie w plikach, drugi po prostu wyświetla listę plików.
Opcja Caleba jest ładniejsza, mniej naciśnięć klawiszy.
źródło
xargs
polega na tym, że oczekuje, że jego dane wejściowe będą cytowane w szczególny sposób,find
który nie daje rezultatów. Więcfind … | xargs …
nie działa, jeśli masz nazwy plików zawierające białe znaki lub\'"
.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.xargs
radzenia sobie z nazwami plików w Linuksie jestfind ... -print0 | xargs -0
użycie NUL jako separatora. Alternatywa -xargs -d '\n'
zastosowanie separatora nowej linii, 99% niezawodności.Znajdź to jeden ze sposobów i możesz spróbować,
the_silver_searcher
a następnie wystarczyPrzeszukuje chrome we wszystkich plikach (włączając podkatalogi) i jest szybszy niż znajdź
źródło
Aby wyświetlić listę plików zamiast wierszy:
lub:
źródło
Oto przykład tego, jak zwykle używam find / exec ...
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):
źródło
find . -name "*.py" -exec fgrep -l hello {} \;
- wypisze nazwy plików pasujących plików i nic więcej