найти результаты по Zcat, а затем направиться - PullRequest
11 голосов
/ 27 июля 2010

Я пытаюсь найти определенную строку во многих gziped csv-файлах, строка находится в первой строке, и я думал, что нужно получить первую строку каждого файла, комбинируя find, zcat и head.Но я не могу заставить их работать вместе.

$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 ...

Хотя я решил проблему, написав скрипт bash, перебирая файлы и записывая во временный файл, было бы здорово узнать, что ясделал неправильно, как это сделать, и если есть другие способы сделать это.

Ответы [ 4 ]

7 голосов
/ 27 июля 2010

Вы должны найти, что это будет работать:

find . -name "*.gz" | while read -r file; do zcat -f "$file" | head -n 1; done
3 голосов
/ 27 июля 2010

Это сработало так, как вы просили.

head выполнил свою работу, напечатал одну строку и вышел. zcat, работавший под эгидой xargs, попытался написать в закрытую трубу и получил роковой SIGPIPE за свои усилия. Xargs сообщил, почему его ребенок умер.

Чтобы получить желаемое поведение, вам понадобится find -exec ... конструкция или пользовательский zhead для передачи xargs.

добавлен ненужный код, который я нашел за холодильником :

#!/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

Он обработал 10 тыс. Файлов в / usr / share / man примерно за минуту.

1 голос
/ 09 августа 2010

Если у вас установлена ​​GNU Parallel http://www.gnu.org/software/parallel/:

find . -name '*.gz' | parallel 'zcat {} | head -n1'

Смотрите вступительное видео для GNU Parallel по адресу http://www.youtube.com/watch?v=OpaiGYxkSuQ

0 голосов
/ 27 июля 2010
zcat -r * 2>/dev/null | awk -vRS= -vFS="\n" '{print $1}'
...