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.

Était-ce utile?

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}'
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top