Einer meiner Lieblings-BASH-Befehle ist:
find . -name '*.*' -exec grep 'SearchString' {} /dev/null \;
durchsucht den Inhalt aller Dateien im und unterhalb des aktuellen Verzeichnisses nach dem angegebenen SearchString. Als Entwickler hat sich dies manchmal als nützlich erwiesen.
Aufgrund meines aktuellen Projekts und der Struktur meiner Codebasis möchte ich diesen BASH-Befehl jedoch weiterentwickeln, indem ich keine Dateien in oder unter einem Verzeichnis suche, das ".svn" enthält, oder Dateien, die .svn enthalten ende mit ".html"
Die MAN Seite für den Fund hat mich allerdings etwas verwirrt. Ich habe versucht, -Prune zu verwenden, und es hat mich seltsam verhalten. Bei dem Versuch, nur die HTML-Seiten zu überspringen (um zu beginnen), habe ich Folgendes versucht:
find . -wholename './*.html' -Prune -exec grep 'SearchString' {} /dev/null \;
und bekam nicht das Verhalten, auf das ich gehofft hatte. Ich denke, ich könnte den Punkt -Prune verpassen. Könnt ihr mir helfen?
Vielen Dank
Sie können die Negativfunktion (!) Von find verwenden, um Dateien mit bestimmten Namen nicht zuzuordnen:
find . ! -name '*.html' ! -path '*.svn*' -exec grep 'SearchString' {} /dev/null \;
Wenn der Name also irgendwo im Pfad auf .html endet oder .svn enthält, stimmt er nicht überein, und die Ausführung wird nicht ausgeführt.
Ich habe seit langer Zeit das gleiche Problem und es gibt verschiedene Lösungen, die in verschiedenen Situationen anwendbar sind:
ack-grep
ist eine Art "Entwickler grep
", die standardmäßig Versionskontrollverzeichnisse und temporäre Dateien überspringt. Auf der Seite man
erfahren Sie, wie Sie nur nach bestimmten Dateitypen suchen und Ihre eigenen definieren .grep
-Optionen --exclude
und --exclude-dir
können sehr einfach zum Überspringen der Verzeichnisse Globs und Single verwendet werden.find . \( -type d -name '.svn' -o -type f -name '*.html' \) -Prune -o -print0 | xargs -0 grep ...
sollte funktionieren, aber die oben genannten Optionen sind auf lange Sicht wahrscheinlich weniger problematisch.Der folgende Befehl find
entfernt Verzeichnisse, deren Namen enthalten .svn
sind. Obwohl er nicht in das Verzeichnis abfällt, wird der beschnittene Pfadname gedruckt ... (-name '*.svn'
ist die Ursache!).
Sie können die Verzeichnisnamen über Folgendes herausfiltern: grep -d skip
, wodurch solche eingegebenen "Verzeichnisnamen" unbemerkt übersprungen werden.
Mit GNU grep können Sie -H
anstelle von /dev/null
verwenden. Als geringfügiges Nebenproblem: \+
kann viel schneller sein als \;
, z. Für 1 Million einzeilige Dateien wurden mit \;
4m20s , mit \+
nur 1,2s benötigt.
Die folgende Methode verwendet xargs
anstelle von -exec
und setzt voraus, dass in keiner Ihrer Dateien names Zeilenumbrüche \n
enthalten sind. Wie hier verwendet, ist xargs
dem \+
von find sehr ähnlich.
xargs
kann Dateinamen übergeben, die aufeinanderfolgende Leerzeichen enthalten, indem das Eingabetrennzeichen mit der Option '\n'
in -d
geändert wird.
Dies schließt Verzeichnisse aus, deren Namen.svn
enthalten, und greift nur auf Dateien zu, die nicht mit .html
enden.
find . \( -name '*.svn*' -Prune -o ! -name '*.html' \) |
xargs -d '\n' grep -Hd skip 'SearchString'