2015-01-02 43 views
1

基本上我想学习如何使用一个子进程(比如proc1)的stdout作为2个或更多其他子进程(比如proc2 & proc3)的stdin蟒蛇。Python:将一个子进程的stdout重定向到2个或更多子进程的stdin

嗨, 我需要zcat一个.gz文件,并使用发送到subprocess.PIPE'cksum'(unix实用程序)和行计数的输出。

我能做到这一点在这样的bash ...

[[email protected]_server 12]$ zcat ABC_C_TPM_26122014.data.gz | tee >(wc -l) >(cksum)| tail -2 

2020090579 112180 

586 

我想要做相同的蟒蛇。

当我做到这一点...

>>> import subprocess 
>>> import os 
>>> fl123 = 'ABC_C_TPM_26122014.data.gz' 
>>> pqr123 = subprocess.Popen(['zcat', fl123], stdout=subprocess.PIPE) 
>>> subprocess.check_output(['cksum'], stdin=pqr123.stdout) 
b'4286000649 256100 \n' 

现在PIPE是空的,所以我将如何得到行数,直到我不会再这样做ZCAT。

我能够很好地在子运行ZCAT两次,并且重新定位到第一ZCAT输出到wc -l和第二ZCAT的输出校验和做到这一点。但是zcat是基于磁盘IO的,速度很慢。所以我想避免它。

帮助...任何Python高手... :)

回答

1

到在Python中实现tee命令的简单方法是手动编写的子流程:

import gzip 
from subprocess import Popen, PIPE 

# zcat ABC_C_TPM_26122014.data.gz | tee >(wc -l) >(cksum) 
with gzip.open("ABC_C_TPM_26122014.data.gz", "rb") as input_file: 
    wc = Popen(['wc', '-l'], stdin=PIPE, bufsize=1, close_fds=True) 
    cksum = Popen(['cksum'], stdin=PIPE, bufsize=1, close_fds=True) 

    line_count = 0 
    for line_count, line in enumerate(input_file, start=1): 
     wc.stdin.write(line) 
     cksum.stdin.write(line) 
    wc.stdin.close() 
    cksum.stdin.close() 
wc.wait() 
cksum.wait() 
print("Line count in the parent: %d" % line_count) 

如果线路输入可以是大的,那么你可以读取数据块的输入:通过线(b'\n'chunk = input_file.read(chunk_size)而不是线。

+0

>>>从子进口POPEN,PIPE >>>进口的gzip >>> >>>与gzip.open( “cbp12co.csv.gz”, “RB”)作为INPUT_FILE: ... WC = POPEN([ 'WC', '-l'],标准输入= PIPE,BUFSIZE = 1,close_fds =真) ...校验和= POPEN([ '校验和'],标准输入= PIPE,BUFSIZE = 1,close_fds = TRUE) ... LINE_COUNT = 0 ... 为LINE_COUNT,在枚举线(INPUT_FILE,开始= 1):... wc.stdin.write(线) ... cksum.stdin.write( line) ... wc.stdin.close() ... cksum.stdin.close() ... wc.wait() File“ “,第10行 wc.wait() ^ SyntaxError:无效语法 >>> – DeeCee

+0

将代码保存到文件中。复制粘贴不适用于普通Python REPL中的多行代码 – jfs

相关问题