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

Nei*_*ner 4 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)
Run Code Online (Sandbox Code Playgroud)

稍后通过调用teradata的fastload来读取管道

"/dev/fd/" + str(zcat_proc.stdout.fileno())
Run Code Online (Sandbox Code Playgroud)

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

Fre*_*Foo 7

不需要任何一个zcat或Awk.计算gzip压缩文件中的行可以完成

import gzip

nlines = sum(1 for ln in gzip.open("/path/to/file/myfile.gz"))
Run Code Online (Sandbox Code Playgroud)

如果你想对这些行做其他事情,比如将它们传递给另一个进程,那就行了

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