Wie kann ich alle Verzeichnisse und Unterverzeichnisse rekursiv grep
?
find . | xargs grep "texthere" *
grep -r "texthere" .
Der erste Parameter stellt den zu suchenden regulären Ausdruck dar, während der zweite das zu durchsuchende Verzeichnis darstellt. In diesem Fall steht .
für das aktuelle Verzeichnis.
Hinweis: Dies funktioniert für GNU grep, und auf einigen Plattformen wie Solaris müssen Sie GNU grep anstelle der Legacy-Implementierung verwenden. Für Solaris ist dies der Befehl ggrep
.
Wenn Sie die Erweiterung oder das Muster der gewünschten Datei kennen, können Sie auch die Option --include
verwenden:
grep -r --include "*.txt" texthere .
Sie können auch Dateien erwähnen, die mit --exclude
ausgeschlossen werden sollen.
Wenn Sie häufig nach Code suchen, ist Ag (The Silver Searcher) eine viel schnellere Alternative zu grep, die für die Suche nach Code angepasst ist. Beispielsweise ist es standardmäßig rekursiv und ignoriert Dateien und Verzeichnisse, die in .gitignore
aufgelistet sind, automatisch, sodass Sie nicht immer dieselben umständlichen Ausschlussoptionen für grep oder find übergeben müssen.
Ebenfalls:
find ./ -type f -print0 | xargs -0 grep "foo"
aber grep -r
ist eine bessere Antwort.
Ich benutze jetzt immer (auch unter Windows mit GoW - Gnu unter Windows ):
grep --include="*.xxx" -nRHI "my Text to grep" *
Das beinhaltet die folgenden Optionen:
--include=PATTERN
Verwenden Sie Verzeichnisse, die nur nach Dateien suchen, die mit
PATTERN
übereinstimmen.
-n, --line-number
Stellen Sie jeder Ausgabezeile die Zeilennummer in der Eingabedatei voran.
(Hinweis: phuclv fügt in den Kommentaren hinzu, dass -n
die Leistung stark verringert , daher möchten Sie diese Option möglicherweise überspringen.)
-R, -r, --recursive
Lesen Sie alle Dateien in jedem Verzeichnis rekursiv. Dies entspricht der Option
-d recurse
.
-H, --with-filename
Gibt den Dateinamen für jede Übereinstimmung aus.
-I
Verarbeiten Sie eine Binärdatei so, als ob sie keine übereinstimmenden Daten enthielte.
Dies entspricht der Option--binary-files=without-match
.
Und ich kann 'i
' (-nRHIi
) hinzufügen, wenn die Groß- und Kleinschreibung nicht berücksichtigt werden soll.
Ich kann erhalten:
/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43: 'git.hidden' => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21: $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32: $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20: protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170: * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176: return $this->hidden;
...
In POSIX-Systemen finden Sie den Parameter -r
für grep
nicht und Ihr grep -rn "stuff" .
wird nicht ausgeführt. Wenn Sie jedoch den Befehl find
verwenden, geschieht Folgendes:
find . -type f -exec grep -n "stuff" {} \; -print
Einverstanden mit Solaris
und HP-UX
.
**
_Die Verwendung von _grep -r
_ funktioniert, kann jedoch zu einem Übermaß führen, insbesondere in großen Ordnern.
Für eine praktischere Verwendung ist hier die Syntax, die Globbing-Syntax (_**
_) verwendet:
_grep "texthere" **/*.txt
_
das greift nur auf bestimmte Dateien mit einem ausgewählten Muster zu. Es funktioniert für unterstützte Shells wie Bash +4 oder zsh .
Führen Sie zum Aktivieren dieser Funktion Folgendes aus: _shopt -s globstar
_.
Siehe auch: Wie finde ich alle Dateien, die bestimmten Text enthalten, unter Linux?
git grep
Verwenden Sie für Projekte unter Git-Versionskontrolle:
_git grep "pattern"
_
das ist viel schneller.
ripgrep
Bei größeren Projekten ist das schnellste Grepping-Tool ripgrep
, das Dateien standardmäßig rekursiv greift:
_rg "pattern" .
_
Es basiert auf Rusts Regex-Engine , das endliche Automaten, SIMD und aggressive wörtliche Optimierungen verwendet, um die Suche sehr schnell zu machen. Überprüfen Sie die detaillierte Analyse hier .
nur die Dateinamen können ebenfalls nützlich sein
grep -r -l "foo" .
Um den Namen von files
mit path
zu finden, der rekursiv das bestimmte string
enthält, verwenden Sie den folgenden Befehl für UNIX
:
find . | xargs grep "searched-string"
für Linux
:
grep -r "searched-string" .
suchen Sie eine Datei auf dem UNIX
Server
find . -type f -name file_name
suchen Sie eine Datei auf dem Linux-Server
find . -name file_name
Wenn Sie nur aktuellen Verzeichnissen und keinen symbolischen Links folgen möchten,
grep -r "thingToBeFound" directory
Wenn Sie sowohl symbolischen Links als auch tatsächlichen Verzeichnissen folgen möchten (achten Sie auf unendliche Rekursionen),
grep -R "thing to be found" directory
Da Sie versuchen, rekursiv zu greifen, können die folgenden Optionen auch für Sie nützlich sein:
-H: outputs the filename with the line
-n: outputs the line number in the file
Wenn Sie also alle Dateien, die Darth Vader enthalten, im aktuellen Verzeichnis oder in Unterverzeichnissen suchen und den Dateinamen und die Zeilennummer erfassen möchten, aber nicht möchten, dass die Rekursion symbolischen Links folgt, lautet der Befehl
grep -rnH "Darth Vader" .
Wenn Sie alle Erwähnungen der Word-Katze im Verzeichnis finden möchten
/home/adam/Desktop/TomAndJerry
und du bist gerade im Verzeichnis
/home/adam/Desktop/WorldDominationPlot
wenn Sie den Dateinamen, aber nicht die Zeilennummer einer Instanz der Zeichenfolge "cats" erfassen möchten und die Rekursion symbolischen Verknüpfungen folgen soll, können Sie eine der folgenden Aktionen ausführen
grep -RH "cats" ../TomAndJerry #relative directory
grep -RH "cats" /home/adam/Desktop/TomAndJerry #absolute directory
Quelle:
"grep --help" ausführen
Eine kurze Einführung in symbolische Links für alle, die diese Antwort lesen und durch meinen Verweis verwirrt sind: https://www.nixtutor.com/freebsd/understanding-symbolic-links/
ag ist meine derzeitige Lieblingsmethode github.com/ggreer/the_silver_searcher . Es ist im Grunde dasselbe wie ack, aber mit ein paar weiteren Optimierungen.
Hier ist ein kurzer Benchmark. Ich lösche den Cache vor jedem Test (siehe https://askubuntu.com/questions/155768/how-do-i-clean-or-disable-the-memory-cache )
[email protected]$ sync && echo 3 | Sudo tee /proc/sys/vm/drop_caches
3
[email protected]$ time grep -r "hey ya" .
real 0m9.458s
user 0m0.368s
sys 0m3.788s
[email protected]:$ sync && echo 3 | Sudo tee /proc/sys/vm/drop_caches
3
[email protected]$ time ack-grep "hey ya" .
real 0m6.296s
user 0m0.716s
sys 0m1.056s
[email protected]$ sync && echo 3 | Sudo tee /proc/sys/vm/drop_caches
3
[email protected]$ time ag "hey ya" .
real 0m5.641s
user 0m0.356s
sys 0m3.444s
[email protected]$ time ag "hey ya" . #test without first clearing cache
real 0m0.154s
user 0m0.224s
sys 0m0.172s
Dies ist die, die für meinen Fall auf meinem aktuellen Computer funktioniert hat (Git Bash unter Windows 7):
find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"
Ich vergesse immer die -print0 und -0 für Pfade mit Leerzeichen.
BEARBEITEN: Mein bevorzugtes Tool ist jetzt stattdessen ripgrep: https://github.com/BurntSushi/ripgrep/releases . Es ist sehr schnell und hat bessere Standardeinstellungen (wie standardmäßig rekursiv). Gleiches Beispiel wie meine ursprüngliche Antwort, aber mit ripgrep: rg -g "*.cs" "content pattern"
Wenn Sie in allen Dateien einer Verzeichnisstruktur nach einem bestimmten Inhalt suchen, können Sie find
verwenden, da klarer ist, was Sie tun:
find -type f -exec grep -l "texthere" {} +
Beachten Sie, dass -l
(Kleinbuchstabe von L) den Namen der Datei anzeigt, die den Text enthält. Entfernen Sie es, wenn Sie stattdessen das Match selbst drucken möchten. Oder verwenden Sie -H
, um die Datei zusammen mit dem Match abzurufen. Alles in allem sind andere Alternativen:
find -type f -exec grep -Hn "texthere" {} +
Wobei -n
die Zeilennummer druckt.
Das sollte funktionieren:
grep -R "texthere" *
grep -r "texthere" .
(Kündigungsfrist am Ende)
(^ credit: https://stackoverflow.com/a/1987928/1438029 )
Erläuterung:
grep -r "texthere" /
(rekursiv grep alle Verzeichnisse und Unterverzeichnisse)
grep -r "texthere" .
(rekursiv grep diese Verzeichnisse und Unterverzeichnisse)
grep [options] PATTERN [FILE...]
[Optionen]
-R, -r, --recursive
Lesen Sie alle Dateien in jedem Verzeichnis rekursiv.
Dies entspricht der Option
-d recurse
oder--directories=recurse
.
$ grep --help
$ grep --help |grep recursive
-r, --recursive like --directories=recurse
-R, --dereference-recursive
ack
( http://beyondgrep.com/ )
2018 möchten Sie ripgrep
oder the-silver-searcher
verwenden, weil sie viel schneller sind als die Alternativen.
Hier ist ein Verzeichnis mit 336 Unterverzeichnissen der ersten Ebene:
% find . -maxdepth 1 -type d | wc -l
336
% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py' 1.24s user 2.23s system 283% cpu 1.222 total
% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$' 2.71s user 1.55s system 116% cpu 3.651 total
% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py' 1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs 6.65s user 0.49s system 32% cpu 22.164 total
Unter OSX wird ripgrep
: brew install ripgrep
installiert. Dies installiert silver-searcher
: brew install the_silver_searcher
.
Verwenden Sie in meinem IBM AIX Server (Betriebssystemversion: AIX 5.2) Folgendes:
find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \;
dies gibt den Pfad/Dateinamen und die relative Zeilennummer in der Datei wie folgt aus:
./inc/xxxx_x.h
2865:/** Beschreibung: stringYouWannaFind * /
sowieso klappt es bei mir :)
Nachfolgend finden Sie den Befehl zum rekursiven Durchsuchen einer String
-Umgebung in Unix
und Linux
.
für UNIX
lautet der Befehl:
find . -name "string to be searched" -exec grep "text" "{}" \;
für Linux
lautet der Befehl:
grep -r "string to be searched" .
Ich denke, das ist es, was du zu schreiben versuchst
grep myText $(find .)
und dies kann etwas anderes hilfreich sein, wenn Sie die Dateien finden möchten, die grep getroffen hat
grep myText $(find .) | cut -d : -f 1 | sort | uniq
Für eine Liste der verfügbaren Flags:
grep --help
Gibt alle Übereinstimmungen für den regulären Ausdruck texthere im aktuellen Verzeichnis mit der entsprechenden Zeilennummer zurück:
grep -rn "texthere" .
Gibt alle Übereinstimmungen für texthere zurück, beginnend mit dem Stammverzeichnis, mit der entsprechenden Zeilennummer und ohne Berücksichtigung von Groß- und Kleinschreibung:
grep -rni "texthere" /
hier verwendete Flags:
-r
rekursiv-n
Zeilennummer mit Ausgabe drucken-i
Groß-/Kleinschreibung ignorierenBeachten Sie, dass bei find . -type f | xargs grep whatever
Arten von Lösungen die Fehlermeldung "Argument list to long" angezeigt wird, wenn zu viele Dateien gefunden wurden.
Die beste Wette ist grep -r
, aber wenn dies nicht verfügbar ist, verwenden Sie stattdessen find . -type f -exec grep -H whatever {} \;
.
Nur zum Spaß, eine schnelle und schmutzige Suche in * .txt-Dateien, wenn die @ christangrant-Antwort zu viel für die Eingabe ist :-)
grep -r texthere .|grep .txt
Hier ist eine rekursive (leicht mit Bash und Sh getestete) Funktion, die alle Unterordner eines bestimmten Ordners ($ 1) durchläuft und mit grep
nach einem bestimmten String ($ 3) in bestimmten Dateien ($ 2) sucht:
$ cat script.sh
#!/bin/sh
cd "$1"
loop () {
for i in *
do
if [ -d "$i" ]
then
# echo entering "$i"
cd "$i"
loop "$1" "$2"
fi
done
if [ -f "$1" ]
then
grep -l "$2" "$PWD/$1"
fi
cd ..
}
loop "$2" "$3"
Ausführen und eine Beispielausgabe:
$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename