Dateinamen nur mit gefundenem Muster suchen und ausgeben
15
Ich habe das oft benutzt. Die Verbesserung, die ich erreichen möchte, besteht darin, Echo-Dateinamen zu vermeiden, die in grep nicht übereinstimmen. Besser dazu?
for file in `find . -name "*.py"`; do echo $file; grep something $file; done
würde den Dateinamen vor jeder übereinstimmenden Zeile ausgeben (wir fügen /dev/nullden Fall hinzu, dass es nur eine übereinstimmende Datei gibt, da grepder Dateiname nicht gedruckt wird, wenn nur eine Datei zum Einsehen übergeben wird. Die GNU-Implementierung von grephat eine -HOption dafür als Alternative).
find .-name '*.py'-exec grep -l something {}+
würde nur die Dateinamen der Dateien drucken, die mindestens eine übereinstimmende Zeile haben.
Um den Dateinamen vor den übereinstimmenden Zeilen auszudrucken , können Sie stattdessen awk verwenden:
Oder rufen Sie grepzweimal für jede Datei auf - obwohl dies weniger effizient wäre, da mindestens ein grepBefehl und bis zu zwei für jede Datei ausgeführt würden (und lesen Sie den Inhalt der Datei zweimal):
Je nach Version der GNU grep, grepaussehen kann oder nicht innerhalb Symlinks oder Traverse symbolische Links zu Verzeichnissen. Möglicherweise gibt es auch Unterschiede in der Behandlung anderer Arten von nicht regulären Dateien.
Stéphane Chazelas
5
Sie können grep anweisen, den Dateinamen in die Ausgabe aufzunehmen. Wenn es also eine Übereinstimmung gibt, wird diese auf der Konsole angezeigt. Wenn in einer Datei keine Übereinstimmung vorliegt, wird für diese Datei keine Zeile gedruckt.
find . -name "*.py" | xargs grep -n -H something
Aus dem man grep:
-H Always print filename headers with output lines
-n, --line-number
Each output line is preceded by its relative line number in the file, starting at line 1. The line number counter is reset for each file processed.
This option is ignored if -c, -L, -l, or -q is specified.
Wenn Ihre Dateien Namen mit Leerzeichen enthalten, müssen Sie die Pipe umschalten, um NUL-Zeichen als Trennzeichen zu verwenden. Der vollständige Befehl sieht nun folgendermaßen aus:
Es gibt grep Alternativen, deren Ergebnisse standardmäßig im gewünschten Format ausgegeben werden. Die 2 beliebtesten, die ich kenne, sind ag(aka "der silberne Sucher") und ack. agwird als schnellere Alternative zu beworben ack.
Ich kann es Ihnen hier nicht zeigen, aber die Ausgabe ist ordentlich gefärbt. Ich bekomme die Dateinamen in Olivgrün, die Zeilennummern in Goldgelb und das passende Teil in jeder Zeile in Blutrot. Die Farben sind jedoch anpassbar.
Antworten:
würde den Dateinamen nach den übereinstimmenden Zeilen ausgeben.
würde den Dateinamen vor jeder übereinstimmenden Zeile ausgeben (wir fügen
/dev/null
den Fall hinzu, dass es nur eine übereinstimmende Datei gibt, dagrep
der Dateiname nicht gedruckt wird, wenn nur eine Datei zum Einsehen übergeben wird. Die GNU-Implementierung vongrep
hat eine-H
Option dafür als Alternative).würde nur die Dateinamen der Dateien drucken, die mindestens eine übereinstimmende Zeile haben.
Um den Dateinamen vor den übereinstimmenden Zeilen auszudrucken , können Sie stattdessen awk verwenden:
Oder rufen Sie
grep
zweimal für jede Datei auf - obwohl dies weniger effizient wäre, da mindestens eingrep
Befehl und bis zu zwei für jede Datei ausgeführt würden (und lesen Sie den Inhalt der Datei zweimal):In jedem Fall möchten Sie nicht die Ausgabe von
find
so durchlaufen und denken Sie daran, Ihre Variablen in Anführungszeichen zu setzen .Wenn Sie eine Shell-Schleife mit GNU-Werkzeugen verwenden wollten:
(Funktioniert auch mit FreeBSD und Derivaten).
quelle
Wenn Sie GNU grep verwenden, können Sie die Option
-r
oder verwenden--recursive
, um diese einfache Suche für Sie durchzuführen:Sie benötigen nur,
find
wenn Sie erweiterte Prädikate benötigen.quelle
grep
,grep
aussehen kann oder nicht innerhalb Symlinks oder Traverse symbolische Links zu Verzeichnissen. Möglicherweise gibt es auch Unterschiede in der Behandlung anderer Arten von nicht regulären Dateien.Sie können grep anweisen, den Dateinamen in die Ausgabe aufzunehmen. Wenn es also eine Übereinstimmung gibt, wird diese auf der Konsole angezeigt. Wenn in einer Datei keine Übereinstimmung vorliegt, wird für diese Datei keine Zeile gedruckt.
Aus dem
man grep
:Wenn Ihre Dateien Namen mit Leerzeichen enthalten, müssen Sie die Pipe umschalten, um NUL-Zeichen als Trennzeichen zu verwenden. Der vollständige Befehl sieht nun folgendermaßen aus:
quelle
Sie können versuchen, etwas wie:
Dieser Befehl exec grep für jede Datei, die mit dem Befehl find und seiner Standardfunktion find ermittelt wurde
quelle
Verwenden Sie das
-l
Argument.Eine sinnvollere Verwendung wäre:
quelle
Es gibt
grep
Alternativen, deren Ergebnisse standardmäßig im gewünschten Format ausgegeben werden. Die 2 beliebtesten, die ich kenne, sindag
(aka "der silberne Sucher") undack
.ag
wird als schnellere Alternative zu beworbenack
.Ich kann es Ihnen hier nicht zeigen, aber die Ausgabe ist ordentlich gefärbt. Ich bekomme die Dateinamen in Olivgrün, die Zeilennummern in Goldgelb und das passende Teil in jeder Zeile in Blutrot. Die Farben sind jedoch anpassbar.
quelle