Jak mogę użyć grep do przeszukiwania wielu nieopartych katalogów?

21

Może to brzmieć tak, jakbym zadawał to samo pytanie , ale mam inne wymagania. To jest przykład mojego systemu plików:

  • /kod/
    • wewnętrzny/
      • dev /
      • Główny/
    • publiczny/
      • dev /
      • Główny/
      • wydanie/
    • przybory/

/code/internal/dev/, /code/public/dev/I /code/tools/zawierać podkatalogi dla wielu projektów. Pracuję prawie wyłącznie w gałęziach programistów /code/internal/i /code/public/, i często chcę wyszukać ciąg tekstowy w tych katalogach wraz z /code/tools/(który nie ma gałęzi). W takich przypadkach muszę wykonać trzy osobne polecenia:

$ grep -r "some string" /code/internal/dev/
$ grep -r "some string" /code/public/dev/
$ grep -r "some string" /code/tools/

Chciałbym wiedzieć, czy jest na to jedno polecenie. Jeśli nie, najprawdopodobniej musiałbym napisać prosty skrypt bash.

David Kennedy
źródło

Odpowiedzi:

38

Możesz połączyć kilka ścieżek, aby grep mógł poszukać:

grep -r "some string" /code/internal/dev/ /code/public/dev/ /code/tools/
Artur Szymczak
źródło
To takie oczywiste. Dlaczego o tym nie pomyślałem ?!
David Kennedy,
W rzeczywistości powoduje to błąd, grep: /code/internal/dev/*.cs: No such file or directorychyba że usunę *.cspolecenie z polecenia. To moja wina, ponieważ *.cspierwotnie postawiłem pytanie.
David Kennedy,
14

Jeśli chcesz maksymalnie wykorzystać symbole wieloznaczne (a opublikowana hierarchia jest kompletna), możesz to zrobić

grep -r "some string" /code/{*/dev,tools}/*.cs

Wyjaśnienie:

Pierwszym wykonanym krokiem jest rozszerzenie listy stężeń. foo{bar,baz}quxrozwija się do foobarqux foobazqux. Oznacza to, że dla każdej pozycji na liście jest generowane osobne słowo, z dołączoną częścią przedrostek i postfiks. Możesz zobaczyć, jak to działa, robiąc

echo A{1,2,3,4}B

które wyjścia

A1B A2B A3B A4B

Zauważ, że działa to również z wieloma nawiasami klamrowymi, a także z pustymi argumentami; na przykład

echo {,1,2}{0,1,2}:{2,3}

daje

0:2 0:3 1:2 1:3 2:2 2:3 10:2 10:3 11:2 11:3 12:2 12:3 20:2 20:3 21:2 21:3 22:2 22:3

Więc po rozwinięciu nawiasu twoje polecenie wygląda następująco:

grep -r "some string" /code/*/dev/*.cs /code/tools/*.cs

Następnym krokiem jest rozwinięcie symboli wieloznacznych. Wiesz już o tym *.cs, ale działa również w przypadku katalogów pośrednich; ponadto, jeśli /następuje, pasują tylko katalogi. Dlatego biorąc pod uwagę twoją hierarchię (i tworzenie nazw .csplików), otrzymasz polecenie:

grep -r "some string" /code/internal/dev/file1.cs /code/internal/dev/file2.cs /code/public/dev/file3.cs /code/tools/file4.cs /code/tools/file5.cs

Dopiero po tym, jak grepto wszystko się stanie, jest wywoływany z tą listą argumentów (zauważ, że to samo dzieje się z twoimi oryginalnymi poleceniami; grepnigdy nie widzi *; rozwijanie odbywa się całkowicie bashprzed wywołaniem grep).

celtschk
źródło