Wie rekursiv rekursiv grep
alle Verzeichnisse und Unterverzeichnisse?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
funktioniert bei Redhat Linux nicht. Ich erhalte den Fehler "Keine Übereinstimmung".
Wie rekursiv rekursiv grep
alle Verzeichnisse und Unterverzeichnisse?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
funktioniert bei Redhat Linux nicht. Ich erhalte den Fehler "Keine Übereinstimmung".
Antworten:
grep -r "texthere" .
Der erste Parameter stellt den regulären Ausdruck dar, nach dem gesucht werden soll, während der zweite das Verzeichnis darstellt, nach dem gesucht werden soll. In diesem Fall .
bedeutet das aktuelle Verzeichnis.
Hinweis: Dies funktioniert für GNU grep. Auf einigen Plattformen wie Solaris müssen Sie GNU grep im Gegensatz zur Legacy-Implementierung speziell verwenden. Für Solaris ist dies der ggrep
Befehl.
AIX 5.3
zum Beispiel mitgeliefert wird .
Wenn Sie die Erweiterung oder das Muster der gewünschten Datei kennen, können Sie auch die folgende --include
Option verwenden:
grep -r --include "*.txt" texthere .
Sie können auch Dateien erwähnen, mit denen ausgeschlossen werden soll --exclude
.
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. Zum Beispiel ist es standardmäßig rekursiv und ignoriert automatisch die darin aufgeführten Dateien und Verzeichnisse .gitignore
, sodass Sie nicht immer dieselben umständlichen Ausschlussoptionen übergeben müssen, um sie zu durchsuchen oder zu suchen.
=
funktioniert unter Ubuntu einwandfrei . PS: Das sollte ein Backticked-Bereich sein, aber der SO-Markdown-Parser ist fehlgeschlagen.
grep
, nicht für die Ag gestimmt , nur damit Sie wissen :)
--include "*.txt" --include "*.TXT"
Ebenfalls:
find ./ -type f -print0 | xargs -0 grep "foo"
ist aber grep -r
eine bessere antwort.
find . -type f -exec grep "foo" '{}' \;
funktioniert dies gut, wenn dies unterstützt wird.
find ./ -type f -print0 | xargs -0 grep "foo"
Ich benutze jetzt immer (auch unter Windows mit GoW - Gnu unter Windows ):
grep --include="*.xxx" -nRHI "my Text to grep" *
Dazu gehören folgende Optionen:
--include=PATTERN
In Verzeichnissen nur nach übereinstimmenden Dateien suchen
PATTERN
.
-n, --line-number
Stellen Sie jeder Ausgabezeile die Zeilennummer in der Eingabedatei voran.
(Hinweis: phuclv fügt in den Kommentaren hinzu , was -n
die Leistung erheblich verringert. Daher möchten Sie diese Option möglicherweise überspringen.)
-R, -r, --recursive
Lesen Sie alle Dateien unter jedem Verzeichnis rekursiv. Dies entspricht der
-d recurse
Option.
-H, --with-filename
Drucken Sie den Dateinamen für jede Übereinstimmung.
-I
Verarbeiten Sie eine Binärdatei so, als ob sie keine übereinstimmenden Daten enthält.
Dies entspricht der--binary-files=without-match
Option.
Und ich kann ' i
' ( -nRHIi
) hinzufügen , wenn ich zwischen Groß- und Kleinschreibung unterscheiden möchte.
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;
...
-R
Option rekursiv ) auf die Ordner angewendet wird.
*
oder .
ist ein Glob-Muster (von der Shell interpretiert): unix.stackexchange.com/a/64695/7490 . ' .
' wählt auch Punktdateien oder Punktordner aus (wie .git/
)
grep -rnI
aber dann habe ich gelernt, dass -n
die Leistung stark abnimmt, also benutze ich es nur, wenn es wirklich gebraucht wird, und normalerweise werde ich es verwenden-rI
In POSIX-Systemen finden Sie keine -r
Parameter für grep
und grep -rn "stuff" .
werden nicht ausgeführt. Wenn Sie jedoch den find
Befehl verwenden, wird Folgendes ausgeführt:
find . -type f -exec grep -n "stuff" {} \; -print
Einverstanden von Solaris
und HP-UX
.
-exec
Option - Symbol {}
ist ein Verweis auf den Dateinamen, der derzeit vom find
Tool gefunden wird (dh etwas mit dem gefundenen Dateinamen zu tun hat). Außerdem -exec
sollte die Option mit ;
Symbol beendet werden (um das Ende der exec-Befehle zu markieren), aber weil dies alles ist Wenn das Symbol in einer Shell ausgeführt wird, sollte es maskiert werden. Mit der -print
Option kann das find
Tool gefundene Dateinamen auf dem Bildschirm ausdrucken.
**
Verwenden von grep -r
Werken, aber es kann zu viel des Guten sein, insbesondere in großen Ordnern.
Für eine praktischere Verwendung ist hier die Syntax, die die Globbing-Syntax ( **
) verwendet:
grep "texthere" **/*.txt
Hiermit werden nur bestimmte Dateien mit einem ausgewählten Muster erfasst. Es funktioniert für unterstützte Shells wie Bash +4 oder zsh .
Führen Sie Folgendes aus, um diese Funktion zu aktivieren : shopt -s globstar
.
Siehe auch: Wie finde ich unter Linux alle Dateien, die bestimmten Text enthalten?
git grep
Verwenden Sie für Projekte unter Git-Versionskontrolle:
git grep "pattern"
das ist viel schneller.
ripgrep
Für größere Projekte ist das schnellste Grepping-Tool ripgrep
das Dateien standardmäßig rekursiv erfasst:
rg "pattern" .
Es basiert auf der Regex-Engine von Rust, die endliche Automaten, SIMD und aggressive Literaloptimierungen verwendet, um die Suche sehr schnell zu machen. Überprüfen Sie die detaillierte Analyse hier .
Um den Namen von files
mit path
rekursiv zu finden, der den jeweiligen string
Befehl 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 tatsächlichen Verzeichnissen und nicht symbolischen Links folgen möchten,
grep -r "thingToBeFound" directory
Wenn Sie symbolischen Links sowie tatsächlichen Verzeichnissen folgen möchten (achten Sie auf unendliche Rekursion),
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 mit Darth Vader im aktuellen Verzeichnis oder in einem beliebigen Unterverzeichnis 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 des Wortes Katze im Verzeichnis finden möchten
/home/adam/Desktop/TomAndJerry
und Sie befinden sich derzeit im Verzeichnis
/home/adam/Desktop/WorldDominationPlot
Wenn Sie den Dateinamen, aber nicht die Zeilennummer einer Instanz der Zeichenfolge "Katzen" erfassen möchten und die Rekursion symbolischen Links folgen soll, wenn sie gefunden werden, 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:
Ausführen von "grep --help"
Eine kurze Einführung in symbolische Links für alle, die diese Antwort lesen und durch meinen Verweis auf sie verwirrt sind: https://www.nixtutor.com/freebsd/understanding-symbolic-links/
ag ist meine Lieblingsmethode, um dies jetzt zu tun. github.com/ggreer/the_silver_searcher . Es ist im Grunde das Gleiche wie ack, aber mit ein paar weiteren Optimierungen.
Hier ist ein kurzer Benchmark. Ich lösche den Cache vor jedem Test (vgl. Https://askubuntu.com/questions/155768/how-do-i-clean-or-disable-the-memory-cache )
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .
real 0m9.458s
user 0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .
real 0m6.296s
user 0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .
real 0m5.641s
user 0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache
real 0m0.154s
user 0m0.224s
sys 0m0.172s
Das sollte funktionieren:
grep -R "texthere" *
Wenn Sie in einer Datei nach einem bestimmten Inhalt in allen Dateien suchen, können Sie diesen verwenden, find
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 die Übereinstimmung selbst drucken möchten. Oder verwenden Sie -H
, um die Datei mit dem Match zusammenzustellen. Insgesamt sind andere Alternativen:
find -type f -exec grep -Hn "texthere" {} +
Wo -n
druckt die Zeilennummer.
find
Lösung, die sowohl unnötige Verwendung xargs
als auch Verwendung +
anstelle von \;
mit -exec
vermeidet, wodurch Tonnen unnötiger Prozessstarts vermieden werden. :-)
Dies ist derjenige, der 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"
grep -r "texthere" .
(Kündigungsfrist am Ende)
(^ credit: https://stackoverflow.com/a/1987928/1438029 )
Klärung:
grep -r "texthere" /
(rekursiv alle Verzeichnisse und Unterverzeichnisse durchsuchen)
grep -r "texthere" .
(rekursiv diese Verzeichnisse und Unterverzeichnisse durchsuchen)
grep [options] PATTERN [FILE...]
[Optionen]
-R, -r, --recursive
Lesen Sie alle Dateien unter 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/ )
Im Jahr 2018 möchten Sie verwenden ripgrep
oder the-silver-searcher
weil sie viel schneller als die Alternativen sind.
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 Folgendes installiert ripgrep
: brew install ripgrep
. Dies installiert silver-searcher
: brew install the_silver_searcher
.
rg
hat ein beträchtlicher Vorteil gegenüber dem Zusammenschustern eines rekursiven grep-Befehls von Grund auf neu. Verwenden von rg
: rg foo
. Verwenden von Unix-Tools : find . | xargs grep foo
. Und wenn eine Ihrer Dateien ein Zitat enthält, müssen Sie verwenden find . -print0 | xargs -0 grep foo
. Wirst du dich daran erinnern, wenn du es ein paar Mal im Jahr verwendest?
find . -type f -exec grep 'regex' {} +
was in der Tat leicht zu merken ist, wenn Sie diese Tools regelmäßig verwenden. Aber wahrscheinlich sollten Sie trotzdem ctags
oder etags
in Ihrem Quellbaum laufen, wenn Sie häufig nach Dingen suchen müssen.
Verwenden Sie in meinem IBM AIX Server (Betriebssystemversion: AIX 5.2):
find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \;
Dadurch werden der Pfad- / Dateiname und die relative Zeilennummer in der Datei wie folgt ausgedruckt:
./inc/xxxx_x.h
2865: / ** Beschreibung: stringYouWannaFind * /
sowieso funktioniert es bei mir :)
Unten finden Sie den Befehl zum String
rekursiven Suchen nach Unix
undLinux
Umwelt.
für UNIX
Befehl ist:
find . -name "string to be searched" -exec grep "text" "{}" \;
für Linux
Befehl ist:
grep -r "string to be searched" .
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 im Stammverzeichnis, mit der entsprechenden Zeilennummer und ohne Berücksichtigung der Groß- und Kleinschreibung:
grep -rni "texthere" /
hier verwendete Flags:
-r
rekursiv -n
Zeilennummer mit Ausgabe drucken -i
Fall ignorierenIch denke, das ist es, was du schreiben willst
grep myText $(find .)
und dies kann etwas anderes hilfreich sein, wenn Sie die Dateien grep hit finden möchten
grep myText $(find .) | cut -d : -f 1 | sort | uniq
Beachten Sie, dass find . -type f | xargs grep whatever
bei verschiedenen Lösungen Fehler auftreten, wenn zu viele Dateien mit find übereinstimmen.
Die beste Wette ist, grep -r
aber wenn das nicht verfügbar ist, verwenden Sie find . -type f -exec grep -H whatever {} \;
stattdessen.
xargs
ist speziell eine Problemumgehung für das Problem "Argumentliste zu lang".
find . -type f | xargs -L 100 grep whatever
xargs
ist standardisiert, um dieses Verhalten sofort zu gewährleisten. "Das xargs
Dienstprogramm muss die Befehlszeilenlänge so begrenzen, dass beim Aufrufen der Befehlszeile die kombinierten Argument- und Umgebungslisten ... {ARG_MAX} -2048 Byte nicht überschreiten."
Hier ist eine rekursive (leicht mit bash und sh getestete) Funktion, die alle Unterordner eines bestimmten Ordners ($ 1) durchläuft und grep
in bestimmten Dateien ($ 2) nach bestimmten Zeichenfolgen ($ 3) 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