【发布时间】:2015-09-18 23:14:32
【问题描述】:
我经常需要对包含标题的文件集合进行排序。因为排序取决于标题的内容,所以这个用例比类似的问题更复杂(例如,Is there a way to ignore header lines in a UNIX sort?)。
我希望使用 Python 来读取文件,输出第一个文件的标题,然后将尾部通过管道传输到排序中。我已经尝试将此作为概念证明:
#!/usr/bin/env python
import io
import subprocess
import sys
header_printed = False
sorter = subprocess.Popen(['sort'], stdin=subprocess.PIPE)
for f in sys.argv[1:]:
fd = io.open(f,'r')
line = fd.readline()
if not header_printed:
print(line)
header_printed = True
sorter.communicate(line)
当以header-sort fileA fileB 调用时,fileA 和 fileB 包含类似的行
c float int
Y 0.557946 413
F 0.501935 852
F 0.768102 709
我明白了:
# sort file 1
Traceback (most recent call last):
File "./archive/bin/pipetest", line 17, in <module>
sorter.communicate(line)
File "/usr/lib/python2.7/subprocess.py", line 785, in communicate
self.stdin.write(input)
ValueError: I/O operation on closed file
问题是通信需要一个字符串,并且管道在写入后关闭。这意味着必须将内容完全读入内存。通信不需要生成器(我试过)。
一个更简单的演示是:
>>> import subprocess
>>> p = subprocess.Popen(['tr', 'a-z', 'A-Z'], stdin=subprocess.PIPE)
>>> p.communicate('hello')
HELLO(None, None)
>>> p.communicate('world')
Traceback (most recent call last):
File "<ipython-input-14-d6873fd0f66a>", line 1, in <module>
p.communicate('world')
File "/usr/lib/python2.7/subprocess.py", line 785, in communicate
self.stdin.write(input)
ValueError: I/O operation on closed file
那么,问题是,在 Python 中将数据流式传输到管道中的正确方法是什么(使用 Popen 或其他方式)?
【问题讨论】:
标签: python pipe subprocess