Ich würde gerne wissen, ob es einen Tipp gibt, den man grep
so schnell wie möglich machen kann. Ich habe eine ziemlich große Basis an Textdateien, um so schnell wie möglich zu suchen. Ich habe sie alle in Kleinbuchstaben geschrieben, damit ich die -i
Option loswerden kann . Dies macht die Suche viel schneller.
Außerdem habe ich herausgefunden, dass -F
und -P
Modi schneller sind als der Standardmodus. Ich verwende den ersteren, wenn die Suchzeichenfolge kein regulärer Ausdruck ist (nur einfacher Text), den letzteren, wenn es sich um einen regulären Ausdruck handelt.
Hat jemand Erfahrung im Beschleunigen grep
? Vielleicht kompilieren Sie es von Grund auf mit einem bestimmten Flag (ich bin unter Linux CentOS), organisieren die Dateien auf eine bestimmte Weise oder machen die Suche auf irgendeine Weise parallel?
grep
, ist es möglicherweise an der Zeit, nach einer Lösung zu suchen, um sie ordnungsgemäß zu indizieren (die "beste" Lösung hängt davon ab, um welche Art von Dateien es sich handelt)."...or maybe make the search parallel in some way?"
Ich würde mich sehr freuen, davon zu hören.grep
sollte in der Lage sein, parallel zu arbeiten, aber ich vermute, dass die Suche immer noch E / A-gebunden ist.ack-grep
?ack-grep
oder besser Ag! geoff.greer.fm/2011/12/27/the-silver-searcher-better-than-ackAntworten:
Versuchen Sie es mit GNU parallel , das ein Beispiel für die Verwendung enthält mit
grep
:Bei großen Dateien kann die Eingabe mit den Argumenten
--pipe
und in mehrere Teile aufgeteilt werden--block
:Sie können es auch über SSH auf mehreren verschiedenen Computern ausführen (SSH-Agent erforderlich, um Kennwörter zu vermeiden):
quelle
--color=always
Sie diese Option, um die Grep-Farbe beizubehalten (dies gilt auch dann, wenn Sie Grep auch in einer Pipe verwenden)find
das-print0
Prädikat hat (die meisten tun es), wäre es vorzuziehen, es zu verwendenfind . -type f -print0 | parallel -0 -k …
. Meine Instanzman(1) parallel
sagt das tatsächlich. Ich vermute auch, dassglobstar
Sie dies noch schneller machen können, wenn Sie nach einem bestimmtenshopt -s globstar; parallel -k -j150% -n 1000 -m fgrep -H -n STRING ::: **/*.c
cat
wenn Siesudo
zugreifen möchtenbigfile
Wenn Sie sehr große Dateien durchsuchen, kann das Festlegen Ihres Gebietsschemas wirklich hilfreich sein.
GNU grep geht im C-Gebietsschema viel schneller als mit UTF-8.
export LC_ALL=C
quelle
Ripgrep behauptet, jetzt der Schnellste zu sein.
https://github.com/BurntSushi/ripgrep
Enthält standardmäßig auch Parallelität
Aus der README
quelle
Anscheinend kann die Verwendung von --mmap auf einigen Systemen helfen:
http://lists.freebsd.org/pipermail/freebsd-current/2010-August/019310.html
quelle
Keine reine Codeverbesserung, aber etwas, das ich hilfreich fand, nachdem ich grep für mehr als 2 Millionen Dateien ausgeführt hatte.
Ich habe den Vorgang auf ein billiges SSD-Laufwerk (120 GB) verschoben. Bei etwa 100 US-Dollar ist dies eine erschwingliche Option, wenn Sie regelmäßig viele Dateien verarbeiten.
quelle
Wenn Sie sich nicht darum kümmern, welche Dateien die Zeichenfolge enthalten, möchten Sie möglicherweise das Lesen und Greifen in zwei Jobs unterteilen, da das
grep
mehrfache Laichen möglicherweise kostspielig ist - einmal für jede kleine Datei.Wenn Sie eine sehr große Datei haben:
parallel -j100% --pipepart --block 100M -a <very large SEEKABLE file> grep <...>
Viele kleine komprimierte Dateien (sortiert nach Inode)
ls -i | sort -n | cut -d' ' -f2 | fgrep \.gz | parallel -j80% --group "gzcat {}" | parallel -j50% --pipe --round-robin -u -N1000 grep <..>
Normalerweise komprimiere ich meine Dateien mit lz4 für maximalen Durchsatz.
Wenn Sie nur den Dateinamen mit der Übereinstimmung möchten:
ls -i | sort -n | cut -d' ' -f2 | fgrep \.gz | parallel -j100% --group "gzcat {} | grep -lq <..> && echo {}
quelle
Aufbauend auf der Antwort von Sandro habe ich mir die Referenz angesehen, die er hier zur Verfügung gestellt hat, und mit BSD grep vs. GNU grep herumgespielt. Meine schnellen Benchmark-Ergebnisse zeigten: GNU grep ist viel, viel schneller.
Also meine Empfehlung zur ursprünglichen Frage "schnellstmögliches grep": Stellen Sie sicher, dass Sie GNU grep anstelle von BSD grep verwenden (was beispielsweise unter MacOS die Standardeinstellung ist).
quelle
Ich persönlich benutze die ag (Silbersucher) anstelle von grep und sie ist viel schneller. Sie können sie auch mit Parallel- und Pipe-Block kombinieren.
https://github.com/ggreer/the_silver_searcher
Update: Ich verwende jetzt https://github.com/BurntSushi/ripgrep, das je nach Anwendungsfall schneller als ag ist.
quelle
Eine Sache, die ich schneller gefunden habe, um grep zum Suchen (insbesondere zum Ändern von Mustern) in einer einzelnen großen Datei zu verwenden, ist die Verwendung von split + grep + xargs mit dem parallelen Flag. Zum Beispiel:
Eine Datei mit IDs, nach denen Sie suchen möchten, in einer großen Datei namens my_ids.txt Name der großen Datei bigfile.txt
Verwenden Sie split, um die Datei in Teile zu teilen:
# Use split to split the file into x number of files, consider your big file # size and try to stay under 26 split files to keep the filenames # easy from split (xa[a-z]), in my example I have 10 million rows in bigfile split -l 1000000 bigfile.txt # Produces output files named xa[a-t] # Now use split files + xargs to iterate and launch parallel greps with output for id in $(cat my_ids.txt) ; do ls xa* | xargs -n 1 -P 20 grep $id >> matches.txt ; done # Here you can tune your parallel greps with -P, in my case I am being greedy # Also be aware that there's no point in allocating more greps than x files
In meinem Fall wurde dadurch ein 17-Stunden-Job in einen 1-Stunden-20-Minuten-Job umgewandelt. Ich bin mir sicher, dass es hier eine Art Glockenkurve in Bezug auf die Effizienz gibt, und natürlich hilft es Ihnen nicht, die verfügbaren Kerne zu überprüfen, aber dies war eine viel bessere Lösung als die oben genannten Kommentare für meine Anforderungen, wie oben angegeben. Dies hat einen zusätzlichen Vorteil gegenüber dem Skript parallel zur Verwendung der meisten (Linux-) nativen Tools.
quelle
cgrep kann, falls verfügbar, um Größenordnungen schneller sein als grep.
quelle
MCE 1.508 enthält ein Dual-Chunk-Level-Wrapper-Skript (Datei, Liste), das viele C-Binärdateien unterstützt. zustimmen, grep, egrep, fgrep und tre-zustimmen.
https://metacpan.org/source/MARIOROY/MCE-1.509/bin/mce_grep
https://metacpan.org/release/MCE
Man muss nicht in Kleinbuchstaben konvertieren, wenn -i schnell ausgeführt werden soll. Übergeben Sie einfach --lang = C an mce_grep.
Die Ausgabereihenfolge bleibt erhalten. Die Ausgabe -n und -b ist ebenfalls korrekt. Leider ist dies bei der auf dieser Seite erwähnten GNU-Parallele nicht der Fall. Ich hatte wirklich gehofft, dass GNU Parallel hier funktioniert. Außerdem führt mce_grep beim Aufrufen der Binärdatei keine Unter-Shell (sh -c / path / to / grep) durch.
Eine weitere Alternative ist das in MCE enthaltene MCE :: Grep-Modul.
quelle
Eine leichte Abweichung vom ursprünglichen Thema: Die indizierten Suchbefehlszeilen-Dienstprogramme aus dem GoogleCodesearch-Projekt sind viel schneller als grep: https://github.com/google/codesearch :
Sobald Sie es kompiliert haben (das Golang- Paket wird benötigt), können Sie einen Ordner indizieren mit:
# index current folder cindex .
Der Index wird unter erstellt
~/.csearchindex
Jetzt können Sie suchen:
# search folders previously indexed with cindex csearch eggs
Ich leite die Ergebnisse immer noch durch grep, um farbige Übereinstimmungen zu erhalten.
quelle