Używam find
i otrzymuję listę plików, przez które chcę grep
przejść. Jak mogę potokować tę listę grep
?
Cóż, ogólnym przypadkiem, który działa z dowolnym poleceniem zapisującym na standardowe wyjście, jest użycie xargs
, które pozwoli ci dołączyć dowolną liczbę argumentów wiersza poleceń na końcu polecenia:
$ find … | xargs grep 'search'
Lub osadzić polecenie w grep
linii za pomocą odwrotnych klawiszy lub $()
, który uruchomi polecenie i zastąpi jego wynik:
$ grep 'search' $(find …)
Zauważ, że te polecenia nie działają, jeśli nazwy plików zawierają spacje lub niektóre inne „dziwne znaki” ( \'"
dla xargs, \[*?
dla $(find …)
).
Jednak w konkretnym przypadku find
możliwości wykonania programu na danych argumentach jest wbudowany:
$ find … -exec grep 'search' {} \;
Wszystko pomiędzy -exec
i ;
jest poleceniem do wykonania; {}
zastępuje się nazwą pliku znalezioną przez find
. Spowoduje to wykonanie osobnego grep
dla każdego pliku; ponieważ grep
może mieć wiele nazw i szukanie ich wszystkich, można zmienić ;
, aby +
powiedzieć znaleźć przejść wszystkie nazwy plików pasujące do grep
naraz:
$ find … -exec grep 'search' {} \+
find ... -type f -print0 | xargs -r0 grep 'search' /dev/null
. CO BYŁO DO OKAZANIA. Chociaż-exec +
jest bardzo wydajny, nie istnieje we wszystkich wersjach find.-exec
raczej niżxargs
. Jeśli użyjesz polecenia-exec
infind
, utworzy on tylko jedną powłokę do grep dla zawartości. Jeśli użyjeszxargs
, utworzy dwie powłoki: jedną dla drugiej,find
a drugą dlaxargs
.$ find … -exec grep 'search' {} \+
forma jest znacznie najszybsza.Niektóre wersje
grep
(np. W niewbudowanym systemie Linux, BSD lub Mac OS X) mają-r
opcję wyszukiwania rekurencyjnego. W OpenBSD użyj-R
(i nie ma--exclude
jak w poniższym przykładzie). Obejmuje to proste kombinacjefind
zgrep
.Jeśli twoja implementacja nie ma
-R
flagi lub jeśli chcesz bardziej wyszukane kryteria dopasowywania plików, możesz użyć-exec
podstawowego z,find
aby ją wykonaćgrep
. Kilka starszychfind
implementacji nie obsługuje-exec
…+
; w tych systemach użyj;
zamiast niego+
(wywoła togrep
raz na plik, więc będzie wolniejszy, ale w przeciwnym razie wynik będzie taki sam). Zwróć uwagę na/dev/null
sztuczkę, która powodujegrep
wyświetlenie nazwy pliku, nawet jeśli jest wywoływana w jednym pliku (GNU grep i FreeBSD / NetBSD / OSX grep mają-H
opcję osiągnięcia tego samego efektu).źródło
GNU grep
ma-H
opcję, aby zawsze drukować nazwę pliku.