Pythonic方法将文件内容发送到管道并在一个步骤中计算#行

时间:2011-12-15 14:45:47

标签: python bash shell awk bigdata

给出> 4gb文件myfile.gz,我需要将它zcat到一个管道供Teradata的fastload使用。我还需要计算文件中的行数。理想情况下,我只想在文件中进行一次传递。我使用awk将整行($ 0)输出到stdout,并通过使用awk的END子句,将行数(awk的NR变量)写入另一个文件描述符(outfile)。

我已经设法使用awk做了这个,但我想知道是否存在更加pythonic的方式。

#!/usr/bin/env python
from subprocess import Popen, PIPE
from os import path

the_file = "/path/to/file/myfile.gz"

outfile = "/tmp/%s.count" % path.basename(the_file)
cmd = ["-c",'zcat %s | awk \'{print $0} END {print NR > "%s"} \' ' % (the_file, outfile)]
zcat_proc = Popen(cmd, stdout = PIPE, shell=True)

稍后通过调用teradata的fastload来消耗管道,该快速读取来自

"/dev/fd/" + str(zcat_proc.stdout.fileno())

这有效,但我想知道是否有可能跳过awk并更好地利用python。我也对其他方法持开放态度。我有多个大文件需要以这种方式处理。

4 个答案:

答案 0 :(得分:7)

不需要zcat或Awk。可以使用

计算gzip压缩文件中的行数
import gzip

nlines = sum(1 for ln in gzip.open("/path/to/file/myfile.gz"))

如果您想对这些行执行其他操作,例如将它们传递给其他进程,请执行

nlines = 0
for ln in gzip.open("/path/to/file/myfile.gz"):
    nlines += 1
    # pass the line to the other process

答案 1 :(得分:3)

计算行和解压缩gzip - 压缩文件可以使用Python及其标准库轻松完成。你可以一次完成所有事情:

import gzip, subprocess, os
fifo_path = "path/to/fastload-fifo"
os.mkfifo(fifo_path)
fastload_fifo = open(fifo_path)
fastload = subprocess.Popen(["fastload", "--read-from", fifo_path],
                            stdin=subprocess.PIPE)
with gzip.open("/path/to/file/myfile.gz") as f:
    for i, line in enumerate(f):
         fastload_fifo.write(line)
    print "Number of lines", i + 1
os.unlink(fifo_path)

我不知道如何调用Fastload - 在调用中替换正确的参数。

答案 2 :(得分:1)

这可以通过一个简单的bash行来完成:

zcat myfile.gz | tee >(wc -l >&2) | fastload

这将在stderr上打印行数。如果您想在其他地方使用它,您可以根据需要重定向wc输出。

答案 3 :(得分:0)

实际上,根本不可能将数据传输到Fastload,所以如果有人在这里发布一个确切的例子,那就太棒了。

关于Fastload配置http://www.info.teradata.com/htmlpubs/DB_TTU_14_00/index.html#page/Load_and_Unload_Utilities/B035_2411_071A/2411Ch03.026.028.html#ww1938556

的Teradata文档

FILE =文件名 关键字短语,指定包含输入数据的数据源的名称。 fileid必须引用常规文件。 具体而言,不支持管道