2009-08-10 12 views
40

Mon problème actuel est que j'ai environ 10 dossiers, qui contiennent des fichiers gzippés (environ 5 chacun en moyenne). Cela fait 50 fichiers à ouvrir et à regarder.trouver une chaîne dans un fichier gzippé dans un dossier

Existe-t-il une méthode plus simple pour savoir si un fichier gzippé dans un dossier a un motif particulier ou pas?

zcat ABC/myzippedfile1.txt.gz | grep "pattern match" 
zcat ABC/myzippedfile2.txt.gz | grep "pattern match" 

Au lieu d'écrire un script, je peux faire la même chose dans une seule ligne, pour tous les dossiers et sous-dossiers?

for f in `ls *.gz`; do echo $f; zcat $f | grep <pattern>; done; 

Répondre

47

zgrep regardera dans les fichiers gzip, a une option récursive -R, et un -H me montrer l'option de nom de fichier:

zgrep -R --include=*.gz -H "pattern match" . 
+12

FWIW, mon zgrep ne supporte pas -R – ZombieDev

+0

@Ned Batchelder, Merci de donner une direction. Mais pour moi suivant travaillé options zgrep "motif" fichiers – hiren

+0

'zgrep -R --include = \ *. Gz -H" motif "' sur zsh – blacktooth

7

utiliser la commande find

find . -name "*.gz" -exec zcat "{}" + |grep "test" 

ou essayez d'utiliser l'option récursive (r) de zcat

+0

-bash-3.00 $ trouver. -name "* .gz" -exec zcat "{}" + | grep "NOT OK" trouver: argument manquant à '-exec ' Quelque chose semble manquer après exec? – gagneet

+0

ça marche pour moi. – ghostdog74

+0

peut-être essayer de changer pour trouver ... +; | grep ... et voyez – ghostdog74

18

Vous n'avez pas besoin zcat ici parce qu'il ya zgrep et zegrep.

Si vous voulez exécuter une commande sur une hiérarchie de répertoires, vous utilisez trouver:

find . -name "*.gz" -exec zgrep ⟨pattern⟩ \{\} \; 

Et aussi « ls *.gz » est inutile dans pour et vous devez simplement utiliser « * .gz " A l'avenir.

+0

Je reçois les lignes qui contiennent ce motif, mais pas le nom du fichier avec cette méthode. Y at-il un moyen d'obtenir cela aussi répertorié? – gagneet

+2

'trouver. -name '* .gz' -print0 | xargs -0 motif zgrep'? – Hasturkun

+2

Vieux truc de grep: trouver. -nom "* .gz" -exec zgrep ⟨pattern⟩/dev/null \ {\} \; # Cela fera croire à grep qu'il y a plus d'un fichier et imprimer le nom du fichier. –

6

comment zgrep ne prennent pas en charge R

Je pense que la solution de « Nietzche-jou » pourrait être une meilleure réponse, mais j'ajouter le -H option pour afficher le nom du fichier quelque chose comme ça

find . -name "*.gz" -exec zgrep -H 'PATTERN' \{\} \; 
+0

Merci pour la commande d'afficher le nom du fichier :) –

6

venir un peu en retard sur ce point, avait un problème similaire et était capable de r esolve en utilisant;

zcat -r /some/dir/here | grep "blah" 

Comme détaillé ici;

http://manpages.ubuntu.com/manpages/quantal/man1/gzip.1.html

Cependant, cela ne montre pas le fichier original que le résultat correspondait à partir, au lieu montrant « (entrée standard) », comme on reveniez d'une pipe. zcat ne semble pas non plus supporter la sortie d'un nom.

En termes de performance, c'est ce que nous avons obtenu; Comme vous pouvez le voir, en utilisant la méthode find|zcat est significativement plus lent

$ alias dropcache="sync && echo 3 > /proc/sys/vm/drop_caches" 

$ find 09/01 | wc -l 
4208 

$ du -chs 09/01 
24M 

$ dropcache; time zcat -r 09/01 > /dev/null 
real 0m3.561s 

$ dropcache; time find 09/01 -iname '*.txt.gz' -exec zcat '{}' \; > /dev/null 
0m38.041s 

que d'utiliser zcat -r lorsqu'ils traitent avec même un petit volume de fichiers. J'ai également été incapable de faire sortir le nom du fichier par zcat (en utilisant -v, le nom du fichier apparaîtra, mais pas sur chaque ligne). Il semblerait qu'il n'existe actuellement aucun outil qui fournisse à la fois la vitesse et la cohérence du nom avec grep (c'est-à-dire l'option -H).

Si vous devez identifier le nom du fichier auquel appartient le résultat, vous devez soit écrire votre propre outil (ce qui peut être fait avec 50 lignes de code Python), soit utiliser la méthode la plus lente. Si vous n'avez pas besoin d'identifier le nom, utilisez zcat -r.

Hope this helps

2

find . -name "*.gz"|xargs zcat | grep "pattern" devrait faire.

Questions connexes