найти результаты, переданные в zcat, а затем в голову

Я пытаюсь найти определенную строку во многих CSV-файлах, сжатых gzip, строка находится в первой строке, и я думал получить первую строку каждого файла, комбинируя 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, перебирая файлы и записывая их во временный файл, было бы здорово узнать, что я сделал неправильно, как это сделать и есть ли другие способы сделать это.


person furedde    schedule 27.07.2010    source источник


Ответы (3)


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

find . -name "*.gz" | while read -r file; do zcat -f "$file" | head -n 1; done
person Dennis Williamson    schedule 27.07.2010
comment
сработало без нареканий, спасибо. не знал, что можно использовать while и читать так, я запомню. - person furedde; 27.07.2010
comment
Вы также можете использовать: for f in *.gz; do zcat $f | head -n 1; done - person arekolek; 29.06.2016
comment
@arekolek: Это не является рекурсивным, если вы не используете shopt -s globstar; for f in **/*.gz, а find является рекурсивным, если вы не ограничиваете его с помощью -maxdepth. - person Dennis Williamson; 29.06.2016

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

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 примерно за минуту.

person msw    schedule 27.07.2010
comment
Хорошее объяснение, я хотел бы проголосовать за вас, и я вернусь, когда наберу 15 повторений. - person furedde; 27.07.2010
comment
Рад помочь. Не беспокойтесь о голосовании, я делаю это не поэтому (и Деннис Уильямсон получил мой голос, потому что это было лучше). - person msw; 27.07.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

person Ole Tange    schedule 09.08.2010