Bearbeiten: Wenn Sie über GNU-Dienstprogramme verfügen, finden Sie in Gilles 'Antwort eine Methode, grep
die die Rekursionsfähigkeiten von GNU verwendet und viel einfacher ist als der find
Ansatz. Wenn Sie nur Dateinamen anzeigen möchten, möchten Sie dennoch die -l
unten beschriebene Option hinzufügen .
Verwenden Sie grep -l word
diese Option, um nur Namen von Dateien zu drucken, die eine Übereinstimmung enthalten.
Wenn Sie alle Dateien im Dateisystem finden möchten .sh
, die am Stamm beginnen /
, find
ist dies das am besten geeignete Tool.
Die tragbarste und effizienteste Empfehlung lautet:
find / -type f -name '*.sh' -exec grep -l word {} + 2>/dev/null
Dies ist ungefähr so lesbar wie es nur geht und ist nicht schwer zu analysieren, wenn Sie die Semantik hinter jeder der Komponenten verstehen.
find /
: find
Ausgehend vom Dateisystemstamm ausführen ,/
-type f
: Nur mit regulären Dateien übereinstimmen
-name '*.sh'
: ... und stimmen nur mit Dateien überein, deren Namen auf enden .sh
-exec ... {} +
: Befehl ausführen, der in ...
übereinstimmenden Dateien in Gruppen angegeben ist, wobei {}
er durch die Dateinamen in der Gruppe ersetzt wird. Die Idee ist, den Befehl innerhalb der Grenzen des Systems ( ARG_MAX
) für so viele Dateien wie möglich gleichzeitig auszuführen . Die Effizienz des {} +
Formulars beruht auf der Minimierung der Häufigkeit, mit der der ...
Befehl aufgerufen werden muss, indem die Anzahl der Dateien maximiert wird, die an jeden Aufruf von übergeben werden ...
.
grep -l word {}
: wobei das {}
gleiche {}
von oben wiederholt wird und durch Dateinamen ersetzt wird. Wie zuvor erläutert, werden grep -l
die Namen von Dateien gedruckt, die eine Übereinstimmung für enthalten word
.
2>/dev/null
: Fehlermeldungen ausblenden (technisch Standardfehler an das Schwarze Loch umleiten /dev/null
). Dies ist aus ästhetischen und praktischen Gründen, da läuft find
auf /
wahrscheinlich in Unmengen von „Zugriff verweigert“ führt Nachrichten Sie nicht kümmern können für Dateien , die Sie nicht über die Berechtigung zum Lesen und Verzeichnisse haben keine Berechtigung zu überqueren.
Es gibt einige Probleme mit den Vorschlägen, die Sie erhalten und in Ihrer Frage veröffentlicht haben. Beide
grep word `find / -name \*.sh 2>/dev/null
und
find / -name "*.sh" 2>/dev/null | xargs grep word
Fehler bei Dateien mit Leerzeichen im Namen. Es ist am besten zu vermeiden, Dateinamen vollständig in die Befehlsersetzung einzufügen. Der erste hat das zusätzliche Problem, möglicherweise auf das ARG_MAX-Limit zu stoßen. Der zweite ist nahe an dem, was ich vorschlage, aber es gibt keinen guten Grund, ihn xargs
hier zu verwenden , ganz zu schweigen davon, dass für eine sichere und korrekte Verwendung xargs
die Portabilität für einige Nur-GNU-Optionen geopfert werden muss ( find -print0 | xargs -0
).
Unter nicht eingebettetem Linux, Cygwin oder einem anderen System mit GNU grep , unter FreeBSD , unter NetBSD und OSX :
Analysieren Sie nicht die Ausgabe von
ls
. Und verwenden Sie keine Befehlssubstitution für die Ausgabe vonfind
, wie jw013 erklärt hat .quelle
grep
.Die Kombination von
grep
undfind
ist in vielen Fällenack
( betterthangrep.com ):Erwägen Sie für Ihr Beispiel die Verwendung
Anmerkungen
ack
.git
,.hg
,.svn
, ...grep
ähnliche Syntax und die gleichen / ähnlichen Argumente wie-i
für "Groß- / Kleinschreibung ignorieren" usw.ack-grep
auf Ihrem System aufgerufen werden (auf Debian-basierten Distributionen, wenn ich mich richtig erinnere)Dateinamenmuster
Die Option
--shell
ist die Abkürzung für--type=shell
und umfasst mehrere Dateitypen: derzeit.sh .bash .csh .tcsh .ksh .zsh
gemäßWenn Sie nur
.sh
Dateien möchten , müssen Sie Ihren eigenen Typ definieren (hinzufügen)sh
und diesen Filter (--sh
) wie folgt verwenden:Dies klingt etwas kompliziert, ermöglicht jedoch die rekursive Suche nach
.sh
Dateien unten/
. Für eine lokale Suche (ohne Angabe des Startverzeichnisses, z. B.\
) wäre es einfacher:quelle
ack
es mir gezeigt hast , ich wusste nie, dass es existiert, sehr praktisch für einen Entwickler!