Ich verwende egrep ( grep -E
) mit einer PATTERN-Datei. ( -f path/to/file
).
Dies geschieht in einer Endlosschleife in einem Textstrom. Dies bedeutet, dass ich nicht ALLE Eingaben auf einmal akkumulieren und an grep übergeben kann (wie *.log
).
Gibt es eine Möglichkeit, grep dazu zu bringen, die NFA, die es erstellt, aus der PATTERN-Datei zu "speichern", um sie für die nächste Ausführung zu verwenden?
Ich habe Google durchsucht und die Dokumentation ohne Glück gelesen.
Ich werde versuchen, es ein bisschen mehr zu erklären. Ich muss eine feste Anzahl von Zeichenfolgen mit regulären Ausdrücken suchen (dies ist kein Teil einer Frage, kann aber gerne etwas anderes vorschlagen), z. B. IP-Adressen, Domains usw. Die Suche erfolgt in einem Feed aus dem Internet. Sie können sich das als Textstrom vorstellen. Ich kann nicht grep
alle Eingaben verwenden, da es sich um einen Stream handelt. Ich kann einen Teil des Streams ansammeln und darauf verwenden grep
(also nicht grep
auf jeder Zeile), aber dies ist auch begrenzt (sagen wir für 30 Sekunden).
Ich weiß grep
, dass eine NFA aus all ihren Mustern erstellt wird (in meinem Fall aus einer Datei). Meine Frage hier lautet also: Kann ich sagen grep
, dass diese NFA für den nächsten Lauf gespeichert werden soll, da sie sich nicht ändern wird? Das würde mir jedes Mal die Zeit sparen, diese NFA aufzubauen.
grep
pro Textzeile ausführen? Woher kommt der Text? Wäretail -f
eine Option?grep
auf diesem Block.grep
mehrmals laufen müssen . Möglicherweise verwandt: Warum ist das Abgleichen von 1250 Zeichenfolgen mit 90.000 Mustern so langsam?grep
soll an einem Textstrom arbeiten, ich verstehe immer noch nicht, warum Sie mehrere Instanzen ausführen müssen. Warum können Sie nicht alle derselbengrep
Instanz zuführen ? Warum müssen Sie sie ansammeln , bevor Sie sie fütterngrep
?Antworten:
Nein, so etwas gibt es nicht. Im Allgemeinen
grep
wären die Kosten für den Start (Verzweigen eines neuen Prozesses, Laden der ausführbaren Datei, gemeinsam genutzte Bibliothek, dynamische Verknüpfung ...) viel höher als das Kompilieren der regulären Ausdrücke, sodass diese Art der Optimierung wenig Sinn macht.Siehe Obwohl Warum ist passend 1250 Saiten gegen 90k Muster so langsam? über einen Fehler in einigen Versionen von GNU
grep
, der es für eine große Anzahl von regulären Ausdrücken besonders langsam machen würde.Möglicherweise können Sie hier vermeiden,
grep
mehrmals zu laufen, indem Sie Ihre Chunks derselbengrep
Instanz zuführen , indem Sie sie beispielsweise als Co-Prozess verwenden und einen Marker verwenden, um das Ende zu erkennen. Mitzsh
und GNUgrep
undawk
andere Implementierungen alsmawk
:Obwohl es vielleicht einfacher ist, das Ganze mit
awk
oderperl
stattdessen zu machen.Wenn Sie die
grep
Ausgabe jedoch nicht benötigen , um für verschiedene Blöcke in verschiedene Dateien zu wechseln, können Sie immer Folgendes tun:quelle
grep
so zu streamen, wie es ist. Vielen Dank.Ist Ihnen bewusst, dass Pipelines blockieren? Wenn Sie etwas an grep weiterleiten und nicht alle Eingaben verfügbar sind, wartet grep, bis es verfügbar ist, und fährt dann fort, als ob die Eingabe die ganze Zeit vorhanden wäre.
BEARBEITEN: Wie Pipelines funktionieren, ist zum Beispiel,
cmd1 | cmd2
dass beide Programme gleichzeitig gestartet werden, mit einem zB 65.536-Byte- "Chunk-Puffer" zwischen ihnen. Wenncmd2
versucht wird zu lesen und dieser Puffer leer ist, wartet er darauf, dass ein Block verfügbar ist. Wenncmd1
versucht wird zu schreiben und dieser Puffer voll ist, wartet er, bis ercmd2
gelesen wird.Nach allem, was ich lesen kann, besteht keine Notwendigkeit, die Eingabe in Stücke zu schneiden und sie separat an grep zu übergeben. Das geht schon automatisch.
EDIT2:
grep
sollte auch die Ergebnisse drucken, sobald sie im Stream gefunden werden. Der Stream muss nicht beendet werden, bevor Sie Ihre Ergebnisse erhalten können.quelle
Vielleicht können Sie "grep für alle Eingaben verwenden"? Verwenden Sie
nc
(netcat) oder überscript
oder über andere ähnliche Tools? Besonders wenn Ihre Musterdatei eine überschaubare Größe hat (sagen wir weniger als 1000 reguläre Ausdrücke).Erstes Beispiel : Sie können
egrep
eine Streaming-Verbindung herstellen: (hier Beispiel mitnc
, aber andere könnten zutreffen)(Hinweis: Sie können sogar:
touch /some/path/results.gz
vor dem Starten desnc
Befehlstail -f
in dieser (leeren) Datei nichts verpassen. Auf jeden Fall enthält die results.gz alles, was Sie abfangen wollten.)zweites Beispiel : Sie könnten sogar
egrep
in einer aktuell ausgeführten Shell-Sitzung (und einen anderen Weg zeigen, um den Fortschritt zu verfolgen):egrep
istgrep
auf den meisten Systemen eine hocheffiziente Version von (siehe einige interessante Informationen unter: https://swtch.com/~rsc/regexp/regexp1.html )quelle
s
ist viel, Mush langsamer als das Matchingsomething
und dies ist viel langsamer als das Matchingsomething even much longer
(letzteres ermöglicht es dem regulären Ausdruck, größer zu werden) Teile der Eingabe, wenn sie unterschiedlich sind) Bei großen Dateien wird die Zeit zum Parsen im Grunde genommen durch das Längenverhältnis "geteilt" (dh das Erfassen eines bekannten Zeichens ist fast 40-mal langsamer als das Abgleichen einer Zeichenfolge mit 40 bekannten Zeichen. Ich habe es nicht getan). t prof es, aber es ist wirklich auffällig.)