2013-03-01 13 views
5

grep ma możliwość wyszukiwania rekursywnie przy użyciu opcji -r. Jednak zastanawiałem się, czy grep ma możliwość wyszukiwania rekurencyjnego ciągu tekstowego dla określonej liczby poziomów podfolderów. Na przykład mam folder root, który ma foldery parent1, parent2, ..., parentN. Każdy folder nadrzędny ma normalne pliki tekstowe i foldery o nazwie child1, child2, ..., childM. Chciałbym uruchomić grep z poziomu katalogu głównego i wyszukać pliki wewnątrz rodziców, nie zaglądając do folderów podrzędnych. Czy istnieje prosty sposób na zrobienie tego?Używanie grep recursively

+1

chcesz zrobić coś takiego: find/path/to/find -name "nameofthefile" lub chcesz ustawić każdy plik na sprawdź ciąg? –

Odpowiedz

6

można spróbować je na:

grep:

--exclude=GLOB 
       Skip files whose base name matches GLOB (using 
       wildcard matching). A file-name glob can use *, 
       ?, and [...] as wildcards, and \ to quote a wildcard 
       or backslash character literally. 

     --exclude-from=FILE 
       Skip files whose base name matches any of the file-name 
       globs read from FILE (using wildcard matching as 
       described under --exclude). 

     --exclude-dir=DIR 
       Exclude directories matching the pattern DIR from 
       recursive searches. 

ani używać tego find | xargs grep

ze znaleziska, można określić poziom

EDIT

Wyjście potoku z jednego polecenia do drugiego jest bardzo powszechne w świecie linux/unix. Założę się, że robisz to codziennie.

echo "abc"|sed 's/a/x/' 
find . -name "*.pyc" |xargs rm 
awk 'blahblah' file | sort |head -n2 
tree|grep 'foo' 
mvn compile|ack 'error' 
... 

Należy zauważyć, że nie wszystkie powyższe przykłady są skuteczne. Są tylko przykładami.

+0

Dziękuję za szybką odpowiedź. Czy mógłbyś wyjaśnić, co | oznacza w twoim przykładzie. Wiem, że można go użyć do wyprowadzenia danych wyjściowych do dest, ale nie rozumiem, jak ma sens przekazywanie wyjścia do innej komendy. W każdym razie próbuję Twojego rozwiązania i wkrótce zaakceptuję Twoją odpowiedź. – Sal

+0

@Sal zobacz edytuj w odpowiedzi, więcej potoków – Kent

10

Jako Kentnotes, nie można tego zrobić z prostym grep; po prostu nie jest wystarczająco silny. Sztuką jest użycie find, aby ustalić, które pliki mają zostać wyszukane i przekazać listę plików, którą find produkuje na grep.

Jeśli prowadzisz man find, dostaniesz stronę człowiekiem wielu opcji find działań. Interesuje nas tutaj -maxdepth.

Zbudujmy potrzebne nam polecenie. Uruchomić polecenia na każdym etapie, aby zobaczyć, jak to wygląda:

  • find . wyświetli wszystkie pliki i foldery, które występują w bieżącym folderze (.) lub dowolnego potomka folderu.

  • find . -maxdepth 1 wyświetli listę wszystkich plików i folderów w bieżącym folderze. find . -maxdepth 2 będzie również wyświetlał listę wszystkich plików i folderów w bieżącym folderze oraz wszystkich natychmiastowych podfolderów. I tak dalej ...

  • Zwróć uwagę, że otrzymujemy również foldery; nie chcemy tego, ponieważ grep nie może przeszukiwać samego folderu, tylko pliki w folderze. Dodaj -type f, aby wyświetlić tylko pliki: find . -maxdepth 2 -type f.

Teraz wiemy, pliki, które chcemy przeszukać, musimy uzyskać grep, aby wyszukać te pliki.Standardowym sposobem, aby to zrobić jest użycie xargs:

find . -maxdepth 2 -type f | xargs grep <text-to-search-for> 

| trwa "standardowe wyjście", aka "stdout", z find (czyli to, co zwykle zobaczyć na ekranie) i rury go do xarg „s„standard input ", aka" stdin ", czyli co by się normalnie stało, gdybyś wpisał się w działający program.

xargs to sprytny mały program, który uruchamia cokolwiek mu powiesz (tutaj, grep <text-to-search-for>), po dodaniu wszystkich argumentów, które otrzymał na stdin. Powoduje to, że grep przeszuka każdy plik znaleziony przez find.

To nie działa, jeśli niektóre z twoich nazw plików zawierają spacje, ponieważ xargs uważa, że ​​przestrzeń dzieli dwa różne nazwy plików, a nie część nazwy jednego pliku. Istnieje kilka sposobów, aby sobie z tym poradzić (ideałem jest po prostu nie używać spacji w nazwach plików), a popularnym jest użycie jednej z ciekawszych funkcji find.

Jeśli dodać -exec argument find, będzie wykonywał wszystko podać się do ; lub +. Jeśli dodasz {} (to jest literalne znaki { i }), zastąpi to listą wszystkich plików. Ponieważ find to robi, wie, że spacje w nazwie pliku powinny znajdować się w nazwie pliku.

Dlatego najlepszym sposobem, aby robić to, co starasz się to w ten sposób:

find . -type f -maxdepth 2 -exec grep <text-to-search-for> {} + 

(Różnica między kończąc + i ; ma znaczenia tutaj, jeśli jesteś zainteresowany to w man find, ale. krótka wersja jest taka, że ​​+ jest szybsza, ale oznacza, że ​​w poleceniu możesz mieć tylko jedną {}).