Suchen Sie nach Dateien, die einen bestimmten Text enthalten

153

In bash möchte ich den Dateinamen (und den Pfad zur Datei) für jede Datei vom Typ zurückgeben, .php|.html|.jsdie die Zeichenfolge enthält, bei der die Groß- und Kleinschreibung nicht berücksichtigt wird"document.cookie" | "setcookie"

Wie würde ich das machen?

Owen
quelle
4
Haben Sie darüber nachgedacht, nur grep zu verwenden? cyberciti.biz/faq/grep-in-bash
Terrance
Dieser Titel ist ziemlich irreführend. "Dateien finden, die einen bestimmten Text enthalten"
Josh C

Antworten:

212
egrep -ir --include=*.{php,html,js} "(document.cookie|setcookie)" .

Das rFlag bedeutet rekursives Suchen (Suchunterverzeichnisse). Die iFlagge bedeutet, dass die Groß- und Kleinschreibung nicht berücksichtigt wird.

Wenn Sie nur Dateinamen möchten, fügen Sie das Flag l(Kleinbuchstaben L) hinzu:

egrep -lir --include=*.{php,html,js} "(document.cookie|setcookie)" .
bear24rw
quelle
das schien bei mir nicht zu funktionieren (zumindest nicht auf dem Mac) .... hängt nur ... egrep -lir --include = * "repo" egrep: Warnung: rekursive Suche nach stdin
Dean Hiller
13
Sie haben vergessen, den Pfad zur Suche hinzuzufügen. Der Pfad ist '.' im obigen Beispiel. In Ihrem Fall wartet das Skript darauf, dass die Eingabe auf stdin sucht. Versuchen Sie: egrep -lir --include = * "repo" / (oder einen anderen Pfad)
LodeRunner
1
grep -E ... >egrep ...
Aman
Ich habe einen Fehler grep: (error|fail): No such file or directoryauf Ubuntu Desktop 16 erhalten. irgendwelche Hinweise?
Nam G VU
Damit dies funktioniert, musste ich das * mit \ überspringen. so habe ich--include=\*.{php,html,js}
Mehrad Mahmoudian
53

Versuchen Sie etwas wie grep -r -n -i --include="*.html *.php *.js" searchstrinhere .

das -imacht es fallunempfindlich

Das .am Ende bedeutet, dass Sie von Ihrem aktuellen Verzeichnis aus starten möchten. Dies kann durch ein beliebiges Verzeichnis ersetzt werden.

Die -rMittel tun dies rekursiv, direkt im Verzeichnisbaum

Das -ndruckt die Zeilennummer für Übereinstimmungen.

Mit --includekönnen Sie Dateinamen und Erweiterungen hinzufügen. Platzhalter akzeptiert

Weitere Informationen finden Sie unter: http://www.gnu.org/software/grep/

Raoul
quelle
4
Oder verwenden Sie die -lOption (drucken Sie einfach passende Dateinamen) anstelle von-n
Glenn Jackman
15

findsie und grepfür die Zeichenfolge:

Dadurch finden Sie alle Dateien Ihrer 3 Typen in / launch / path und grep für den regulären Ausdruck '(document\.cookie|setcookie)'. Auf 2 Zeilen mit dem Backslash nur zur besseren Lesbarkeit aufteilen ...

find /starting/path -type f -name "*.php" -o -name "*.html" -o -name "*.js" | \
 xargs egrep -i '(document\.cookie|setcookie)'
Michael Berkowski
quelle
1
Wie universelle Verwendung von find, aber meiner Meinung nach besser zu verwenden-exec grep -l 'sth' {} \;
NGix
Danke @Michael Berkowski Auf diese Weise am schnellsten mehr als 5 oder 8 Mal # egrep -ir --include=file.foo "(foo|bar)" /dirauf ~ 500Gb Gewicht Verzeichnis.
Qh0stM4N
9

Klingt nach einem perfekten Job für grepoder vielleicht ack

Oder diese wunderbare Konstruktion:

find . -type f \( -name *.php -o -name *.html -o -name *.js \) -exec grep "document.cookie\|setcookie" /dev/null {} \;
Fredrik Pihl
quelle
+1 Verwenden -exec grep...ist besser als meine xargsMethode, da Leerzeichen in Dateinamen nicht erstickt werden.
Michael Berkowski
@MichaelBerkowski: Sie können es so verwenden, um mit Leerzeichen in Dateinamen umzugehen : find . -type f -print0 | xargs -0 -I {} grep "search_string" {}. Natürlich können auch die anderen Optionen hinzugefügt werden.
Pascal
4
find . -type f -name '*php' -o -name '*js' -o -name '*html' |\
xargs grep -liE 'document\.cookie|setcookie'
nr
quelle
3

Um noch eine Alternative aufzunehmen, können Sie auch Folgendes verwenden:

find "/starting/path" -type f -regextype posix-extended -regex "^.*\.(php|html|js)$" -exec grep -EH '(document\.cookie|setcookie)' {} \;

Wo:

  • -regextype posix-extendedgibt an, findwelche Art von Regex zu erwarten ist
  • -regex "^.*\.(php|html|js)$"teilt finddem regulären Ausdruck selbst mit, dass Dateinamen übereinstimmen müssen
  • -exec grep -EH '(document\.cookie|setcookie)' {} \;weist findan, den Befehl (mit seinen Optionen und Argumenten) auszuführen, der zwischen der -execOption und der \;für jede gefundene Datei angegeben ist, wobei angegeben wird {}, wohin der Dateipfad in diesem Befehl führt.

    während

    • EOption weist grepan, erweiterten regulären Ausdruck zu verwenden (um die Klammern zu unterstützen) und ...
    • HOption weist grepan, Dateipfade vor den Übereinstimmungen zu drucken.

Wenn Sie nur Dateipfade möchten, können Sie Folgendes verwenden:

find "/starting/path" -type f -regextype posix-extended -regex "^.*\.(php|html|js)$" -exec grep -EH '(document\.cookie|setcookie)' {} \; | sed -r 's/(^.*):.*$/\1/' | sort -u

Wo

  • |[pipe] sendet die Ausgabe von findan den nächsten Befehl danach (was seddann ist sort)
  • rOption weist sedan, erweiterten regulären Ausdruck zu verwenden.
  • s/HI/BYE/weist sedan, jedes erste Vorkommen (pro Zeile) von "HI" durch "BYE" und ... zu ersetzen.
  • s/(^.*):.*$/\1/fordert es auf, den regulären Ausdruck zu ersetzen (^.*):.*$(dh eine Gruppe [eingeschlossenes Zeug ()], die alles [ .*= ein oder mehrere Zeichen eines beliebigen Zeichens] vom Anfang der Zeile [ ^] bis zum 'ersten' enthält: 'gefolgt von irgendetwas bis zum Ende von Zeile [ $]) durch die erste Gruppe [ \1] des ersetzten regulären Ausdrucks.
  • uWeist sort an, doppelte Einträge zu entfernen ( sort -uoptional).

... bei weitem nicht der eleganteste Weg. Wie gesagt, meine Absicht ist es, das Spektrum der Möglichkeiten zu erweitern (und auch ausführlichere Erklärungen zu einigen Tools zu geben, die Sie verwenden könnten).

Pedro Vernetti
quelle