Wie kann ich grep verwenden, um mehrere nicht verschachtelte Verzeichnisse zu durchsuchen?

20

Es hört sich vielleicht so an, als würde ich das Gleiche wie diese Frage stellen , aber ich habe andere Anforderungen. Dies ist ein Beispiel für mein Dateisystem:

  • /Code/
    • intern /
      • dev /
      • Main/
    • Öffentlichkeit/
      • dev /
      • Main/
      • Freisetzung/
    • Werkzeuge/

/code/internal/dev/, /code/public/dev/Und /code/tools/Verzeichnisse für mehrere Projekte enthalten. Ich arbeite fast ausschließlich in den dev-Zweigen von /code/internal/und /code/public/und möchte oft nach einer Textzeichenfolge in diesen Verzeichnissen zusammen mit suchen /code/tools/(die keine Zweige hat). In diesen Fällen muss ich drei separate Befehle ausführen:

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

Ich würde gerne wissen, ob es dafür einen einzigen Befehl gibt. Wenn nicht, müsste ich höchstwahrscheinlich ein einfaches Bash-Skript schreiben.

David Kennedy
quelle

Antworten:

38

Sie können mehrere Pfade verketten, nach denen grep suchen soll:

grep -r "some string" /code/internal/dev/ /code/public/dev/ /code/tools/
Artur Szymczak
quelle
Das ist so offensichtlich. Warum habe ich nicht daran gedacht ?!
David Kennedy
Tatsächlich löst dies einen Fehler aus, es grep: /code/internal/dev/*.cs: No such file or directorysei denn, ich entferne den *.csaus dem Befehl. Das ist mein Fehler, weil ich das *.csursprünglich in meine Frage gestellt habe.
David Kennedy
14

Wenn Sie die Platzhalter maximal nutzen möchten (und die von Ihnen bereitgestellte Hierarchie vollständig ist), können Sie dies tun

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

Erläuterung:

Der erste Schritt ist die Erweiterung der Klammerliste. foo{bar,baz}quxerweitert um foobarqux foobazqux. Das heißt, für jedes durch Kommas getrennte Element in der Liste wird ein separates Wort generiert, an das jeweils das Präfix und das Postfix angehängt sind. Sie können sehen, wie das funktioniert

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

welche Ausgänge

A1B A2B A3B A4B

Beachten Sie, dass dies auch mit mehreren geschweiften Klammern und auch mit leeren Argumenten funktioniert. beispielsweise

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

gibt

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

Nach der Klammererweiterung sieht Ihr Befehl also folgendermaßen aus:

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

Der nächste Schritt ist die Platzhaltererweiterung. Sie wissen das bereits für das *.csTeil, aber es funktioniert auch für Zwischenverzeichnisse; Außerdem werden, wenn /folgt, nur Verzeichnisse abgeglichen. In Anbetracht Ihrer Hierarchie (und der Dateinamen für die .csDateien) erhalten Sie daher den Befehl:

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

Erst nachdem all dies geschehen ist, grepwird mit dieser Liste von Argumenten aufgerufen (beachte, dass dasselbe mit deinen ursprünglichen Befehlen passiert ; bekomme das grepnie zu sehen *; Erweiterung, die vollständig von bashvor dem Aufruf durchgeführt wird grep).

Celtschk
quelle