给出> 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。我也对其他方法持开放态度。我有多个大文件需要以这种方式处理。
答案 0 :(得分:7)
不需要zcat
或Awk。可以使用
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,所以如果有人在这里发布一个确切的例子,那就太棒了。
的Teradata文档FILE =文件名 关键字短语,指定包含输入数据的数据源的名称。 fileid必须引用常规文件。 具体而言,不支持管道。