Мне часто приходится сортировать коллекцию файлов, содержащих заголовки. Поскольку сортировка зависит от содержимого заголовка, этот пример использования более сложный, чем аналогичные вопросы (например, Is there a way to ignore header lines in a UNIX sort?).потоковая передача данных в команду с подпроцессом.Popen
Я надеялся использовать 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
Итак, вопрос в том, что правильный путь (с Popen или иным образом) для потоковой передачи данных в трубу в Python?
связанные: [Сортировка текстового файла с помощью Python] (http://stackoverflow.com/q/14465154/4279) – jfs