J'utilise un script pour télécharger régulièrement mes messages gmail qui compresse le .eml brut dans des fichiers .gz. Le script crée un dossier pour chaque jour, puis compresse chaque message dans son propre fichier.
Je voudrais un moyen de rechercher dans cette archive une "chaîne".
Grep seul ne semble pas le faire. J'ai également essayé SearchMonkey.
Si vous voulez grep récursivement dans tous les fichiers .eml.gz du répertoire courant, vous pouvez utiliser:
find . -name \*.eml.gz -print0 | xargs -0 zgrep "STRING"
Vous devez échapper au premier *
pour que le Shell ne l'interprète pas. -print0
indique à find d'imprimer un caractère nul après chaque fichier trouvé; xargs -0
lit à partir de l'entrée standard et exécute la commande après pour chaque fichier; zgrep
fonctionne comme grep
, mais décompresse d'abord le fichier.
Il y a beaucoup de confusion ici car il n'y a pas qu'un seul zgrep
. J'ai deux versions sur mon système, zgrep
de gzip
et zgrep
de zutils
. Le premier n'est qu'un script wrapper qui appelle gzip -cdfq
. Il ne prend pas en charge le -r, --recursive
commutateur.1
Ce dernier est un c++
programme et prend en charge le -r, --recursive
option.
Fonctionnement zgrep --version | head -n 1
révélera lequel (le cas échéant) d'entre eux est la valeur par défaut:
zgrep (gzip) 1.6
est le script wrapper,
zgrep (zutils) 1.3
est l'exécutable cpp
.
Si vous avez ce dernier, vous pouvez exécuter:
zgrep 'pattern' -r --format=gz /path/to/dir
Quoi qu'il en soit, comme suggéré, find
+ zgrep
fonctionnera aussi bien avec l'une ou l'autre version de zgrep
:
find /path/to/dir -name '*.gz' -exec zgrep -- 'pattern' {} +
Si zgrep
est absent de votre système (très peu probable), vous pouvez essayer avec:
find /path/to/dir -name '*.gz' -exec sh -c 'gzip -cd "$0" | grep -- "pattern"' {} \;
mais il y a un inconvénient majeur: vous ne saurez pas où sont les correspondances car il n'y a pas de nom de fichier ajouté aux lignes correspondantes.
ag
est une variante de grep
, avec quelques fonctionnalités supplémentaires Nice.
Donc:
ag -r -z your-pattern-goes-here folder
S'il n'est pas installé,
apt-get install silversearcher-ag (debian and friends)
yum install the_silver_searcher (Fedora)
brew install the_silver_searcher (mac)
La récursivité seule est facile:
-r, --recursive
Read all files under each directory, recursively, following
symbolic links only if they are on the command line. This is
equivalent to the -d recurse option.
-R, --dereference-recursive
Read all files under each directory, recursively. Follow all
symbolic links, unlike -r.
Cependant, pour les fichiers compressés, vous avez besoin de quelque chose comme:
shopt globstar
for file in /path/to/directory/**/*gz; do zcat ""$file" | grep pattern; done
path/to/directory
doit être le répertoire parent contenant les sous-répertoires de chaque jour.
zgrep
est la réponse évidente mais, malheureusement, il ne prend pas en charge le -r
drapeau. De man zgrep
:
Ces options grep entraîneront la fin de zgrep avec un code d'erreur: (- [d rR zZ] | --di * | --exc * | --inc * | --rec * | - nu *).
Si votre système a zgrep, vous pouvez simplement
zgrep -irs your-pattern-goes-here the-folder-to-search-goes-here/
Si votre système n'a pas zgrep, vous pouvez utiliser la commande find pour exécuter zcat et grep sur chaque fichier comme ceci:
find the-folder-to-search-goes-here/ -name '*.gz' \ -exec sh -c 'echo "Searching {}" ; zcat "{}" | grep your-pattern-goes-here ' \;
xzgrep -l "chaîne" ./*/*.eml.gz
xzgrep est un dérivé des utilitaires zgrep (moins/bin/xzgrep)
Depuis la page Man:
xzgrep appelle grep (1) sur des fichiers qui peuvent être non compressés ou compressés avec xz (1), lzma (1), gzip (1), bzip2 (1) ou lzop (1). Toutes les options spécifiées sont transmises directement à grep (1).
-l affiche le nom du fichier correspondant
-R pour la récursivité ne fonctionnera pas car il est spécifiquement interdit dans le script, mais un simple globbing Shell devrait nous y amener
./*/*.eml.gz
à partir d'un chemin relatif où ./today/sample.eml.gz, correspond à toutes les instances qui sont un niveau en dessous de notre position relative dans le shell, qui se termine par ".eml.gz"