Ich verwende ein Skript, um meine Google Mail-Nachrichten regelmäßig herunterzuladen, mit dem die RAW-EML in GZ-Dateien komprimiert wird. Das Skript erstellt für jeden Tag einen Ordner und komprimiert dann jede Nachricht in eine eigene Datei.
Ich möchte in diesem Archiv nach einem "String" suchen.
Grep allein scheint es nicht zu tun. Ich habe auch SearchMonkey ausprobiert.
zgrep
:zgrep - search possibly compressed files for a regular expression
Antworten:
Wenn Sie alle .eml.gz-Dateien im aktuellen Verzeichnis rekursiv bearbeiten möchten, können Sie Folgendes verwenden:
Sie müssen zuerst das
*
Escapezeichen setzen, damit die Shell es nicht interpretiert.-print0
weist find an, nach jeder gefundenen Datei ein Nullzeichen zu drucken;xargs -0
Liest von der Standardeingabe und führt den Befehl danach für jede Datei aus.zgrep
funktioniert wiegrep
, dekomprimiert aber zuerst die Datei.quelle
zgrep
scheint tatsächlich schneller alsgrep
auf unkomprimierten Dateien ausgeführt. Dies muss daran liegen, dass komprimierte Dateien schneller von der Festplatte gelesen und dekomprimiert werden können als nicht komprimierte Dateien von der Festplatte.xargs
verwendet standardmäßig Leerzeichen (Whitespace). Sicher, in Dateien befinden sich fast nie Zeilenumbrüche, aber Leerzeichen sind keine Seltenheit (selbst wenn die meisten UNIXy-Typen sie verachten). Das heißt, Sie können noch einfacher vereinfachen, ohne sich um Whitespace kümmern zu müssen:find . -name '*.eml.gz' -exec zgrep "STRING" {} +
So erhalten Sie die gleichen Argumente pro Startxargs
, die Sicherheit von-print0
/-0
und das alles, ohne den Aufwand für einen zusätzlichen Prozessstart und Piping, und das ziemlich präzise.-exec
mit+
ist POSIX angegeben, daher sollte es meines Wissens nach auf den meisten neueren UNIX-ähnlichen Systemen sein.ABCLog04_18_18_2_21.gz
Gibt es eine Möglichkeit, rekursiv nach Dateien zu suchen, die mit ABC * beginnen? Ich habe versucht,\*.eml.gz
in Ihrem obigen Beispiel durch zu ersetzenABCLog*
und erhalte eine Fehlermeldung zum Dateiformat:find: paths must precede expression: ABCLog-2018-03-12-10-16-1.log.gz Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
Hier herrscht viel Verwirrung, weil es nicht nur eine gibt
zgrep
. Ich habe zwei Versionen auf meinem System,zgrep
vongzip
undzgrep
vonzutils
. Ersteres ist nur ein Wrapper-Skript, das aufgerufen wirdgzip -cdfq
. Der-r, --recursive
Schalter wird nicht unterstützt . 1Letzteres ist ein
c++
Programm und unterstützt die-r, --recursive
Option.Beim Laufen
zgrep --version | head -n 1
wird angezeigt, welche davon (falls vorhanden) die Standardeinstellung ist:ist das Wrapper-Skript,
ist die
cpp
ausführbare Datei.Wenn Sie Letzteres haben, können Sie Folgendes ausführen:
Auf jeden Fall funktioniert
find
+ , wie vorgeschlagen,zgrep
mit beiden Versionen vonzgrep
:Wenn
zgrep
in Ihrem System etwas fehlt (höchst unwahrscheinlich), können Sie Folgendes versuchen:Aber es gibt einen großen Nachteil: Sie werden nicht wissen, wo die Übereinstimmungen sind, da den übereinstimmenden Zeilen kein Dateiname vorangestellt ist.
1: weil es problematisch wäre
quelle
zgrep
von zutils nicht verfügbar ist kannst du es mit in Ubuntu installierensudo apt-get install zutils
.grep -n
,zgrep -n
wird Zeile no.s. drucken Es steht im Handbuch ...ag
ist eine Variante vongrep
, mit ein paar netten Extras.Damit:
Wenn nicht installiert,
quelle
ag: truncated file: Success
als Ergebnis. Soll ich eine andere Flagge hinzufügen?Rekursion allein ist einfach:
Für komprimierte Dateien benötigen Sie jedoch Folgendes:
path/to/directory
sollte das übergeordnete Verzeichnis sein, das die Unterverzeichnisse für jeden Tag enthält.zgrep
ist die offensichtliche Antwort, aber leider wird die-r
Flagge nicht unterstützt . Vonman zgrep
:quelle
Wenn Ihr System über zgrep verfügt, können Sie dies einfach tun
zgrep -irs your-pattern-goes-here the-folder-to-search-goes-here/
Wenn Ihr System nicht über zgrep verfügt, können Sie den Befehl find verwenden , um zcat und grep für jede Datei wie folgt auszuführen:
find the-folder-to-search-goes-here/ -name '*.gz' \ -exec sh -c 'echo "Searching {}" ; zcat "{}" | grep your-pattern-goes-here ' \;
quelle
Searching ~/gmvault-db/db/2015-02/03/whatever.gz
zgrep
wird die-r
Flagge aus irgendeinem Grund nicht nehmen . Das ist erwähnt inman zgrep
(siehe auch meine Antwort).xzgrep ist eine Ableitung der zgrep-Utils (less / bin / xzgrep)
Von der Manpage:
-l gibt den passenden Dateinamen aus
-R für die Rekursion funktioniert nicht, da dies im Skript ausdrücklich verboten ist. Ein einfaches Shell-Globbing sollte uns jedoch dahin bringen
Von einem relativen Pfad aus, in dem ./today/sample.eml.gz auf allen Instanzen übereinstimmt, die eine Ebene unter unserer relativen Position in der Shell liegen und mit ".eml.gz" endet.
quelle