trouver les résultats redirigés vers zcat puis vers head
Question
J'essaie de rechercher une certaine chaîne dans de nombreux fichiers csv gzipés, la chaîne est située à la première ligne et ma pensée était d'obtenir la première ligne de chaque fichier en combinant find, zcat et head.Mais je n'arrive pas à les faire travailler ensemble.
$find . -name "*.gz" -print | xargs zcat -f | head -1
20051114083300,1070074.00,0.00000000
xargs: zcat: terminated by signal 13
example file:
$zcat 113.gz | head
20050629171845,1069335.50,-1.00000000
20050629171930,1069315.00,-1.00000000
20050629172015,1069382.50,-1.00000000
.. and 2 milion rows like these ...
Bien que j'aie résolu le problème en écrivant un script bash, en parcourant les fichiers et en écrivant dans un fichier temporaire, ce serait formidable de savoir ce que j'ai fait de mal, comment le faire et s'il pourrait y avoir d'autres façons de s'y prendre.
La solution
Vous devriez trouver que cela fonctionnera :
find . -name "*.gz" | while read -r file; do zcat -f "$file" | head -n 1; done
Autres conseils
Cela a fonctionné comme vous l'avez demandé.
head
a fait son travail, a imprimé une ligne et est sorti.zcat
alors exécuté sous les auspices de xargs
a tenté d'écrire dans un tuyau fermé et a reçu un SIGPIPE fatal pour ses efforts.Ayant son enfant mourir, xargs rapporta le pourquoi.
Pour obtenir le comportement souhaité, vous auriez besoin d'une construction find -exec ...
ou d'une zhead
personnalisée à donner à xargs.
ajout de code indésirable que j'ai trouvé derrière le frigo :
#!/usr/bin/python
"""zhead - poor man's zcat file... | head -n
no argument error checking, prefers to continue in the face of
IO errors, with diagnostic to stderr
sample usage: find ... | xargs zhead.py -1"""
import gzip
import sys
if sys.argv[1].startswith('-'):
nlines = int(sys.argv[1][1:])
start = 2
else:
nlines = 10
start = 1
for zfile in sys.argv[start:]:
try:
zin = gzip.open(zfile)
for i in range(nlines):
line = zin.readline()
if not line:
break
print line,
except Exception as err:
print >> sys.stderr, zfile, err
finally:
try:
zin.close()
except:
pass
Il a traité 10 000 fichiers dans /usr/share/man en une minute environ.
Si vous avez installé GNU Parallel http://www.gnu.org/software/parallel/ :
find . -name '*.gz' | parallel 'zcat {} | head -n1'
Regardez la vidéo d'introduction à GNU Parallel à http://www.youtube.com/watch?v=OpaiGYxkSuQ
zcat -r * 2>/dev/null | awk -vRS= -vFS="\n" '{print $1}'