jak wykonać operację grep na wszystkich plikach w katalogu

219

Pracuję z Xenserver i chcę wykonać polecenie na każdym pliku znajdującym się w katalogu, wyrzucając niektóre elementy z danych wyjściowych polecenia i dołączając je do pliku.

Mam jasność co do polecenia, którego chcę użyć, i jak w razie potrzeby wyodrębnić ciąg (ciągi).

Ale nie jestem do końca pewien, w jaki sposób mam wykonać to polecenie na każdym pliku, przechodząc do następnego, dopóki nie zostaną znalezione żadne pliki.

użytkownik2147075
źródło

Odpowiedzi:

228

grep $PATTERN *byłoby wystarczające. Domyślnie grep pomija wszystkie podkatalogi. Jeśli jednak chcesz je przeskoczyć, tak grep -r $PATTERN *jest.

umi
źródło
37
„grep -r $ WZORZEC”. jest wystarczający. Dla rekurencyjnego grepa nie musisz określać wszystkich plików
Cougar
1
Jak dołączyć wiele rozszerzeń? Na przykład. „* .cpp”, „* .h”?
Tomáš Zato - Przywróć Monikę
1
@ Tomáš Zato, po prostu dostarczyć wszystkie swoje wzorce plików zamiast *: grep $PATTERN *.cpp *.h. Jeśli potrzebujesz bardziej szczegółowych reguł dla tego, które pliki powinny być grepowane, użyj findpolecenia (sprawdź odpowiedź Roba).
umi
@umi Jeśli uruchomię grep -r x .wyniki pochodzą ze wszystkich plików wszystkich rozszerzeń. Jeśli uruchomię, grep -r x *.scssnie otrzymam żadnych wyników.
Chris
1
@Chris możliwe, że nie masz *.scssplików w bieżącym katalogu, ale gdzieś głębiej w podkatalogach, więc grep nie przegląda wszystkich żądanych plików. Powinieneś użyć --includeopcji, aby powiedzieć grepowi, aby szukał rekurencyjnie plików pasujących do określonych wzorców: grep -r x --include '*.scss' . (zwróć uwagę na cudzysłowy, uniemożliwiają one rozwinięcie wzorca przez powłokę). Lub po prostu użyjfind (patrz odpowiedź Roba).
umi
169

W Linuksie zwykle używam tego polecenia, aby rekurencyjnie grepować dla określonego tekstu w katalogu

grep -rni "string" *

gdzie,

r = rekurencyjny, tzn. przeszukaj podkatalogi w bieżącym katalogu
n = wydrukuj numery linii na standardowe wyjście
i = wyszukiwanie bez rozróżniania wielkości liter

Narain
źródło
32

Użyj znajdź. Poważnie, jest to najlepszy sposób, ponieważ wtedy naprawdę możesz zobaczyć, na jakich plikach działa:

find . -name "*.sql" -exec grep -H "slow" {} \;

Uwaga: -H jest specyficzne dla komputerów Mac, w wynikach pokazuje nazwę pliku.

Obrabować
źródło
7
Jeśli zdecydujesz się użyć find, przepuszczanie danych wyjściowych xargszamiast korzystania z -exectego będzie znacznie szybsze, ponieważ -execspawnuje nowy proces dla każdego grepa, a narzut staje się znaczny przy dużej liczbie plików. Obowiązują standardowe ostrzeżenia dotyczące spacji w nazwach plików xargs.
Barton Chittenden,
2
Jak by to dokładnie wyglądało? Zawsze zapominam o xargsskładni.
Brian Peterson
3
@BrianPeterson byłoby coś takiego: find . -iname "*.sql" -print0 | xargs -0 grep "slow"
MediaVince
4

Aby wyszukiwać we wszystkich podkatalogach, ale tylko w określonych typach plików , użyj grep z--include .

Na przykład wyszukiwanie rekurencyjne w bieżącym katalogu dla tekstu w * .yml i * .yaml:

grep "text to search" -r . --include=*.{yml,yaml}
Noam Manos
źródło
1

Jeśli chcesz wykonać wiele poleceń, możesz użyć:

for I in `ls *.sql`
do
    grep "foo" $I >> foo.log
    grep "bar" $I >> bar.log
done
bryan
źródło