将 header 添加到 python 中子进程的标准输出
add header to stdout of a subprocess in python
我正在将几个数据帧合并为一个并使用 unix sort
对它们进行排序。在我编写最终排序数据之前,我想向该输出添加一个 prefix/header。
所以,我的代码是这样的:
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)
但是,上面的 doe 将 my_cols
放在最终输出文件的末尾(即 mergedAndSorted.txt)
我也试过替换:
sort_data=io.StringIO(my_cols)
但这给了我预期的错误。
如何将 header 添加到子进程输出的开头。我相信这可以通过简单的代码更改来实现。
您的代码存在缓冲问题; 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 文件描述符,这些写入可能会先于 [=13] =].
这正是您在 subprocess
中将文件用作管道时发生的情况。这个好像不能直接解释,但是可以从Frequently Used Arguments:
推断
stdin, stdout and stderr specify the executed program’s standard input, standard output and standard error file handles, respectively. Valid values are PIPE
, DEVNULL
, an existing file descriptor (a positive integer), an existing file object, and None
.
这非常强烈地暗示——如果你足够了解管道在 *nix 和 Windows 上的工作方式——它将实际文件 descriptor/handle 传递给底层的 OS 功能。但它实际上并没有这么说。为了真正确定,您必须检查 the Unix source and Windows source,在那里您可以看到它正在对文件对象调用 fileno
或 msvcrt.get_osfhandle
。
我正在将几个数据帧合并为一个并使用 unix sort
对它们进行排序。在我编写最终排序数据之前,我想向该输出添加一个 prefix/header。
所以,我的代码是这样的:
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)
但是,上面的 doe 将 my_cols
放在最终输出文件的末尾(即 mergedAndSorted.txt)
我也试过替换:
sort_data=io.StringIO(my_cols)
但这给了我预期的错误。
如何将 header 添加到子进程输出的开头。我相信这可以通过简单的代码更改来实现。
您的代码存在缓冲问题; 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 文件描述符,这些写入可能会先于 [=13] =].
这正是您在 subprocess
中将文件用作管道时发生的情况。这个好像不能直接解释,但是可以从Frequently Used Arguments:
stdin, stdout and stderr specify the executed program’s standard input, standard output and standard error file handles, respectively. Valid values are
PIPE
,DEVNULL
, an existing file descriptor (a positive integer), an existing file object, andNone
.
这非常强烈地暗示——如果你足够了解管道在 *nix 和 Windows 上的工作方式——它将实际文件 descriptor/handle 传递给底层的 OS 功能。但它实际上并没有这么说。为了真正确定,您必须检查 the Unix source and Windows source,在那里您可以看到它正在对文件对象调用 fileno
或 msvcrt.get_osfhandle
。