我将几个数据帧合并为一个数据帧,并使用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)
但正如我所预期的那样,这给了我一个错误。
如何将头添加到子流程输出开头。我相信这可以通过简单的代码更改来实现。
发布于 2018-06-02 02:46:45
你的代码的问题是缓冲问题;tldr是你可以像这样修复它:
sort_data.write(my_cols + '\n')
sort_data.flush()
subprocess.run(my_cmd, stdout=sort_data)
当您在文本模式下打开文件时,您打开的是一个缓冲文件。写操作进入缓冲区,文件对象不一定立即将它们刷新到磁盘。(还有从Unicode到字节的流编码,但这并没有真正增加新的问题,它只是添加了两层,在这两层中可能会发生相同的事情,所以让我们忽略它。)
只要您的所有写操作都是针对缓冲文件对象的,这就很好-它们在缓冲区中被正确排序,因此它们在磁盘上也被正确排序。
但是,如果您写入底层sort_data.buffer.raw
磁盘文件或sort_data.fileno()
OS文件描述符,则这些写入可能会先于进入sort_data
的写入。
标准输入、标准输出和标准错误文件句柄分别指定执行程序的标准输入、标准输出和标准错误文件句柄。有效值包括
PIPE
、DEVNULL
、现有文件描述符(正整数)、现有文件对象和None
。
这意味着-如果您对*nix和Windows上管道的工作方式有足够的了解-它会将实际的文件描述符/句柄传递给底层的OS功能。但它实际上并没有这么说。要真正确保这一点,您必须检查the Unix source和Windows source,在这两个命令中,您可以看到它正在对文件对象调用fileno
或msvcrt.get_osfhandle
。
https://stackoverflow.com/questions/50649160
复制相似问题