Kiedy chcę przeszukać całe drzewo w poszukiwaniu jakiejś zawartości, używam
find . -type f -print0 | xargs -0 grep <search_string>
Czy istnieje lepszy sposób na zrobienie tego pod względem wydajności lub zwięzłości?
Kiedy chcę przeszukać całe drzewo w poszukiwaniu jakiejś zawartości, używam
find . -type f -print0 | xargs -0 grep <search_string>
Czy istnieje lepszy sposób na zrobienie tego pod względem wydajności lub zwięzłości?
Odpowiedzi:
Sprawdź, czy opcja grepwsparcia -r(w przypadku ponownego wystąpienia ):
grep -r <search_string> .
--exclude-dirwydajności, a my mamy zwycięzcę!
grepw najnowszych dystrybucjach FreeBSD i Linux go obsługuje. A dlaczego --exclude-dir? Nie prosiłeś o przeszukanie całego drzewa ?
--exclude-dirjest w rzeczywistości przydatny w moim przypadku użycia (ponieważ części poddrzewa są duże, ale bezużyteczne) i zapytałem o wydajność ... ale masz rację, nie jest to konieczne.
--exclude-dirjest wyłączne dla GNU grep. (-:
Nieoptymalna odpowiedź: Zamiast przesyłać dane wyjściowe finddo grep, możesz po prostu uruchomić
find . -type f -exec grep 'research' {} '+'
i voila, jedno polecenie zamiast dwóch!
wyjaśnienie:
find . -type f
znajdź wszystkie zwykłe pliki.
-exec grep 'research'
grep „research”
{}
w znalezionej nazwie pliku
'+'
użyj jednego polecenia dla wszystkich nazw plików, a nie raz dla nazwy pliku.
Uwaga: z ';'tym byłby raz na nazwę pliku.
Poza tym, jeśli używasz go do przetwarzania kodu źródłowego, możesz zajrzeć do niego ack, co jest przeznaczone do łatwego wyszukiwania bitów kodu.
Edytować :
Możesz trochę rozszerzyć te badania. Po pierwsze, możesz użyć -name ''przełącznika, findaby wyszukać pliki z określonym wzorcem nazewnictwa.
Na przykład :
tylko pliki odpowiadające dziennikom: -name '*.log'
tylko pliki odpowiadające nagłówkom c, ale nie możesz trzymać się wielkich lub małych liter dla rozszerzeń plików: -iname *.c
Nb: jak dla grepi ack, -iprzełącznik oznacza w tym przypadku rozróżnianie wielkości liter.
W takim przypadku grep wyświetli się bez koloru i bez numerów linii.
Można to zmienić z --colori -nprzełączniki (numery kolorów i linii w plikach odpowiednio).
Na koniec możesz mieć coś takiego:
find . -name '*.log' -type f -exec grep --color -n 'pattern' {} '+'
na przykład
$ find . -name '*.c' -type f -exec grep -n 'hello' {} '+'
./test2/target.c:1:hello
-name '*.log'To jest szybsze.
Jeśli chcesz przekierować do podkatalogów:
grep -R 'pattern' .
Ta -Ropcja nie jest opcją standardową, ale jest obsługiwana przez większość popularnych grepimplementacji.
-rzamiast -Rpomijać dowiązania symboliczne, gdy dotyczy GNU grep
grepimplementacje GNU wychwytują rekurencje, myślę. W przeciwnym razie zależy to od tego, co rozumiesz przez „drzewo”.
greppowinno zrobić narzędzie . Jeśli użytkownik ma symboliczne pętle linków w swojej strukturze katalogów, to jest problem użytkownika :-)
/sys/devices/cpu/subsystem/devices/cpu/subsystem/devices/cpu/...(-XI jak narzędzia opiekujące się mną (chyba że zapewniają dziwną magię, nazywają „AI”). (-;
Jak wspomniano powyżej -rlub -R(w zależności od pożądanej obsługi dowiązań symbolicznych) jest szybką opcją.
-d <action>Czasami jednak może się przydać.
Przyjemną rzeczą -djest komenda skip, która ucisza „grep: nazwa_katalogu: Jest katalogiem”, gdy chcesz tylko przeskanować bieżący poziom.
$ grep foo *
grep: q2: Is a directory
grep: rt: Is a directory
$ grep -d skip foo *
$
i oczywiście:
$ grep -d recurse foo *
(list of results that don't exist because the word foo isn't in our source code
and I wouldn't publish it anyway).
$
-d skipOpcja jest naprawdę przydatne wewnątrz innego skryptu, dzięki czemu nie trzeba 2> /dev/null. :)
Jeśli masz do czynienia z wieloma plikami, grep działa szybciej, jeśli przycinasz pliki, które musi przeszukać, zamiast grepowania wszystkich plików w podfolderach.
Czasami używam tego formatu:
grep "primary" `find . | grep cpp$`
Znajdź wszystkie pliki w podfolderach .tego końca w cpp. Następnie grep te pliki dla „podstawowego”.
Jeśli chcesz, możesz przesyłać dalej te wyniki do kolejnych wywołań grep:
grep "primary" `find . | grep cpp$` | grep -v "ignoreThis" | grep -i "caseInsensitiveGrep"