grep, aber nur bestimmte Dateierweiterungen


966

Ich arbeite daran, einige Skripte in grepbestimmte Verzeichnisse zu schreiben , aber diese Verzeichnisse enthalten alle Arten von Dateitypen.

Ich möchte grepnur .hund .cppvorerst, aber vielleicht ein paar andere in der Zukunft.

Bisher habe ich:

{ grep -r -i CP_Image ~/path1/;

grep -r -i CP_Image ~/path2/;

grep -r -i CP_Image ~/path3/;

grep -r -i CP_Image ~/path4/;

grep -r -i CP_Image ~/path5/;} 

| mailx -s GREP email@domain.com

Kann mir jemand zeigen, wie ich jetzt nur die spezifischen Dateierweiterungen hinzufügen würde?


13
Versucht grep -r -i CP_Image ~/path1/*.{h,cpp}?

8
Verwenden Sie den Silver Searcher : ag -i CP_Image ~/path[1-5] | mailx -s GREP email@domain.com. Job erledigt.
Johnsyweb


Verwenden Sie egrep (wahrscheinlich auf Ihrem System vorinstalliert), und verwenden Sie dann einen regulären Ausdruck.
Dogweather

8
Das GNU Jungs wirklich vermasselt , wenn sie hinzugefügt , -rum grepes für Dateien wie die Brüche des UNIX - Mantra mit Werkzeugen suchen zu haben , dass „eine Sache tun und es gut tun“. Es gibt ein perfektes Werkzeug, um Dateien mit einem sehr offensichtlichen Namen zu finden.
Ed Morton

Antworten:


1354

Verwenden Sie einfach den --includeParameter wie folgt:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com

das sollte machen was du willst.

Um die Erklärung aus der Antwort von HoldOffHunger unten zu entnehmen:

  • grep: Befehl

  • -r: rekursiv

  • -i: Fall ignorieren

  • --include \*.cpp: all * .cpp: C ++ - Dateien (Escapezeichen mit \ für den Fall, dass Sie ein Verzeichnis mit Sternchen in den Dateinamen haben)

  • ./: Beginnen Sie im aktuellen Verzeichnis.


123
Für den Datensatz: -r (rekursiv) -i (Ignorieren-Groß- / Kleinschreibung) --include (Suche nur nach Dateien, die dem Dateimuster entsprechen)
Luis

34
Kann weiter optimiert werden aufgrep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345]
zwol

1
@Hong wo ist die Dokumentation, dass -R für symbolische Links ist?
Titus

8
Dieses Beispiel scheint eine hohe Punktzahl zu haben, da es ein so breites Spektrum von Möglichkeiten abdeckt, aber die unten angegebene Antwort von grep -r --include = *. Txt 'searchterm' ./ erklärt wirklich das Wesentliche der Antwort
David Casper

10
Warum nicht doppelte Anführungszeichen anstelle von Backslash verwenden? zB:grep -r -i --include="*.h" --include="*.cpp" CP_Image
Pambda

283

Einige dieser Antworten schienen zu syntaxlastig zu sein, oder sie verursachten Probleme auf meinem Debian-Server. Das hat bei mir perfekt funktioniert:

PHP Revolution: Wie grep ich Dateien unter Linux, aber nur bestimmte Dateierweiterungen?

Nämlich:

grep -r --include=\*.txt 'searchterm' ./

... oder Version ohne Berücksichtigung der Groß- und Kleinschreibung ...

grep -r -i --include=\*.txt 'searchterm' ./
  • grep: Befehl

  • -r: rekursiv

  • -i: Fall ignorieren

  • --include: all * .txt: Textdateien (Escapezeichen mit \ für den Fall, dass Sie ein Verzeichnis mit Sternchen in den Dateinamen haben)

  • 'searchterm': Was zu suchen

  • ./: Beginnen Sie im aktuellen Verzeichnis.


7
Sie sollten der *Verwendung von \*.cppoder entkommen '*.cpp'. Andernfalls wird nicht das erwartete Ergebnis angezeigt, wenn das Arbeitsverzeichnis einige *.txtDateien enthält .
Melebius

@Melebius können Sie erklären, warum es entkommen muss - hat es etwas mit den von Ihnen erwähnten CPP- oder TXT-Erweiterungen zu tun? Oder haben Sie diese nur als Beispiele verwendet?
Simon East

2
@SimonEast Diese Erweiterungen werden in dieser Frage und Antwort verwendet, sonst nichts Besonderes. Es würde wahrscheinlich funktionieren, ohne bei der Verwendung zu entkommen, --include=<pattern>aber es ist wichtig, *mit --include <pattern>(einem Leerzeichen statt =) zu entkommen, das sich ansonsten sehr ähnlich anfühlt.
Melebius

52
grep -rnw "some thing to grep" --include=*.{module,inc,php,js,css,html,htm} ./

3
grep -rn "etwas zu grep" --include = *. {module, inc, c, h} *
ashish

3
Gute Antwort. Sauberer als die auf IMO akzeptierten, aber Sie sollten Suchkriterien hinzufügen, wie @ashish vermerkt
billynoah

Warum ist --includeOption nach Nadel, nicht mit anderen Optionen?
Vladkras

@vladkras, was meinst du Nadel? Ist es --?
Heretoinfinity

50

Wie wäre es mit:

find . -name '*.h' -o -name '*.cpp' -exec grep "CP_Image" {} \; -print

5
Ich würde vorschlagen, diese -nameArgumente zu gruppieren . Wenn Sie dies nicht tun, können seltsame Dinge passieren. find . \( -name '*.h' -o -name '*.cpp' \) -exec grep "CP_Image" {} \; -print
Nullrevolution

Verwenden Sie mit zusätzlichem "-type f", um alle Verzeichnisobjekte zu ignorieren, die nur an Dateien interessiert sind.
Kensai

1
Ich habe diese Methode jahrelang verwendet und sie funktioniert, aber sie ist viel langsamer als rekursives grep, da find's exec für jede zu durchsuchende Datei einen separaten grep-Prozess erzeugt.
Beaudet

Durch das Adressieren des Kommentars von @ beaudet findkönnen optional Argumente gebündelt werden, wodurch Aufrufe des aufgerufenen Prozesses auf ein Minimum reduziert werden. find . \( -name \*.h -o -name \*.cpp \) -exec grep -H CP_Image {} + Dies wird vorgeschlagen, aber in der Antwort von @ fedorqui unten nicht hervorgehoben und ist eine lohnende Verbesserung. Das -Hhier zu grepende Argument ist nützlich, wenn find nur eine einzige übereinstimmende Datei identifiziert. Dies könnte die Verwendung von -printin der Antwort eliminieren . Wenn Ihre Gesamtliste der Dateien ausreichend klein ist, ist {path1,path2}/**/*.{cpp,h}möglicherweise die Verwendung eines rekursiven Shell-Globs (z. B. ) vorzuziehen.
Malcolm

19

Auf HP- und Sun-Servern gibt es keine Option -r. Auf diese Weise hat es auf meinem HP-Server funktioniert

find . -name "*.c" | xargs grep -i "my great text"

-i ist für die Suche nach Zeichenfolgen ohne Berücksichtigung der Groß- und Kleinschreibung


1
Ich bin auf mehrere Server für Webhosting-Unternehmen gestoßen, für die die Option --include für fgrep nicht verfügbar ist. Dies ist die Befehlszeile, die ich in diesen Fällen verwende.
Borgboy

Die Option --include ist auch bei Verwendung von Git für Windows (MinGW / MSys) nicht verfügbar.
Darren Lewis

@DarrenLewis verfügbar in Git Bash für Windows. Aber seltsamerweise fügt es bunte Aliase hinzu, wie llaber nicht --color=autozu grep.
Xeverous

Dies sollte die akzeptierte Antwort für Vollständigkeit, Portabilität und Kürze sein!
Grant Foster

12

Da es darum geht , Dateien zu finden, verwenden wir find!

Mit GNU find können Sie die -regexOption verwenden, um die Dateien im Verzeichnisbaum zu finden, deren Erweiterung entweder .hoder ist .cpp:

find -type f -regex ".*\.\(h\|cpp\)"
#            ^^^^^^^^^^^^^^^^^^^^^^^

Dann geht es nur noch darum, grepjedes seiner Ergebnisse auszuführen :

find -type f -regex ".*\.\(h\|cpp\)" -exec grep "your pattern" {} +

Wenn Sie diese Verteilung des Funds nicht haben, müssen Sie einen Ansatz wie den von Amir Afghani verwenden , -oum Optionen zu verketten ( der Name endet entweder mit .hoder mit.cpp ):

find -type f \( -name '*.h' -o -name '*.cpp' \) -exec grep "your pattern" {} +
#            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Und wenn Sie wirklich verwenden möchten grep, befolgen Sie die angegebene Syntax --include:

grep "your pattern" -r --include=*.{cpp,h}
#                      ^^^^^^^^^^^^^^^^^^^

7

Der einfachste Weg ist

find . -type  f -name '*.extension' | xargs grep -i string 

3

ag (der silberne Sucher) hat dafür eine ziemlich einfache Syntax

       -G --file-search-regex PATTERN
          Only search files whose names match PATTERN.

damit

ag -G *.h -G *.cpp CP_Image <path>

mit ag 2.2.0 musste ich meine flaggen zuletzt setzen:ag _string_to_find_ -G _filename_regex_
ryanrain

3

Die folgende Antwort ist gut:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com

Kann aber aktualisiert werden auf:

grep -r -i --include \*.{h,cpp} CP_Image ~/path[12345] | mailx -s GREP email@domain.com

Welches kann einfacher sein.


1

Sollte "-exec grep" für jeden "-o -name" schreiben

find . -name '*.h' -exec grep -Hn "CP_Image" {} \; -o -name '*.cpp' -exec grep -Hn "CP_Image" {} \;

Oder gruppiere sie nach ()

find . \( -name '*.h' -o -name '*.cpp' \) -exec grep -Hn "CP_Image" {} \;

Option '-Hn' zeigt den Dateinamen und die Zeile an.


1

Ich bin mir bewusst , diese Frage ist ein bisschen veraltet, aber ich möchte das Verfahren teilen , die ich normalerweise finden verwende .c und .h - Dateien:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -H "#include"

oder wenn Sie auch die Zeilennummer benötigen:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -nH "#include"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.