问题 找到通过管道传输到zcat然后到头的结果


我正在尝试在很多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脚本,遍历文件并写入临时文件来解决问题,但知道我做错了什么,怎么做以及是否有其他方法可以解决这个问题会很棒。


8263
2017-07-27 02:21


起源



答案:


你会发现这会起作用:

find . -name "*.gz" | while read -r file; do zcat -f "$file" | head -n 1; done

7
2017-07-27 03:40



工作完美无缺,谢谢。不知道你可以使用的同时阅读,我会记住它。 - furedde
你也可以使用: for f in *.gz; do zcat $f | head -n 1; done - arekolek
@arekolek:除非你使用,否则哪个不是递归的 shopt -s globstar; for f in **/*.gz,而 find 是递归的,除非你用它来限制它 -maxdepth。 - Dennis Williamson


答案:


你会发现这会起作用:

find . -name "*.gz" | while read -r file; do zcat -f "$file" | head -n 1; done

7
2017-07-27 03:40



工作完美无缺,谢谢。不知道你可以使用的同时阅读,我会记住它。 - furedde
你也可以使用: for f in *.gz; do zcat $f | head -n 1; done - arekolek
@arekolek:除非你使用,否则哪个不是递归的 shopt -s globstar; for f in **/*.gz,而 find 是递归的,除非你用它来限制它 -maxdepth。 - Dennis Williamson


它按照你的要求工作。

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

它在大约一分钟内处理了/ usr / share / man中的10k文件。


3
2017-07-27 03:21



很好的解释,我希望我可以投票给你,当我达到15reps时我会回来。 - furedde
很高兴有帮助。不要担心投票,这不是我这样做的原因(丹尼斯威廉姆森得到了我的投票,因为它更好)。 - msw


如果你有GNU Parallel http://www.gnu.org/software/parallel/ 安装:

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

观看介绍视频到GNU Parallel at http://www.youtube.com/watch?v=OpaiGYxkSuQ


1
2017-08-09 18:48





zcat -r * 2>/dev/null | awk -vRS= -vFS="\n" '{print $1}'

0
2017-07-27 02:30