добавить заголовок в стандартный вывод подпроцесса в python - PullRequest
0 голосов
/ 01 июня 2018

Я объединяю несколько фреймов данных в один и сортирую их, используя unix sort.Прежде чем я напишу окончательно отсортированные данные, я хотел бы добавить префикс / заголовок к этому выводу.

Итак, мой код выглядит примерно так:

my_cols =  '\t'.join(['CHROM', 'POS', "REF" ....])

my_cmd = ["sort", "-k1,2", "-V", "final_merged.txt"]

with open(output + 'mergedAndSorted.txt', 'w') as sort_data:
    sort_data.write(my_cols + '\n')  
    subprocess.run(my_cmd, stdout=sort_data)

Но, эта выше точка ставит my_cols в конце конечного выходного файла (то есть mergedAndSorted.txt )

Я также попытался заменить:

sort_data=io.StringIO(my_cols)  

, но это выдает ошибку, поскольку яожидал.


Как добавить этот заголовок в начало вывода подпроцесса.Я считаю, что это может быть достигнуто простым изменением кода.

1 Ответ

0 голосов
/ 01 июня 2018

Проблема с вашим кодом связана с буферизацией;tldr в том, что вы можете исправить это следующим образом:

sort_data.write(my_cols + '\n')
sort_data.flush()
subprocess.run(my_cmd, stdout=sort_data)

Если вы хотите понять, почему это происходит, и как исправление устраняет это:

Когда вы открываете файл в текстовом режимеоткрываешь буферизованный файл.Записи записываются в буфер, и объект file не обязательно немедленно сбрасывает их на диск.(Существует также потоковое кодирование из Unicode в байты, но это на самом деле не добавляет новой проблемы, просто добавляет два слоя, где может происходить одно и то же, поэтому давайте проигнорируем это.)

Покакак все ваши записи в буферизованный файловый объект, это нормально - они должным образом упорядочены в буфере, поэтому они упорядочены должным образом на диске.

Но если вы записываете в базовый sort_data.buffer.raw файл на дискеили в дескрипторе файла sort_data.fileno() OS эти записи могут опережать те, которые шли в sort_data.

И это именно то, что происходит, когда вы используете файл в качестве канала в subprocess.Это не объясняется напрямую, но может быть выведено из Часто используемых аргументов :

stdin , stdout и stderr задает стандартный ввод исполняемой программы, стандартный вывод и дескрипторы стандартного файла ошибок соответственно.Допустимые значения: PIPE, DEVNULL, существующий файловый дескриптор (положительное целое число), существующий файловый объект и None.

Это подразумевает довольно сильно - если вы знаете достаточно оспособ, которым работает конвейер в * nix и Windows - что он передает фактический дескриптор / дескриптор файла в базовую функциональность ОС.Но на самом деле это не говорит об этом.Чтобы быть уверенным, вы должны проверить источник Unix и источник Windows , где вы можете видеть, что он вызывает fileno или msvcrt.get_osfhandle для файловых объектов.

...