在 Python 中逐行写入管道的正确方法
Posted
技术标签:
【中文标题】在 Python 中逐行写入管道的正确方法【英文标题】:correct way to write to pipe line by line in Python 【发布时间】:2013-01-02 18:52:51 【问题描述】:如何从 Python 写入标准输出并同时(通过 Unix 管道)将其提供给另一个程序?例如,如果您有
# write file line by line
with open("myfile") as f:
for line in f:
print line.strip()
但是您希望它逐行转到另一个程序,例如| wc -l
以便它输出 myfile
中的行。怎么可能呢?谢谢。
【问题讨论】:
你试过了吗?您可能会发现这已经可以了 :) 您只需要写入标准输出(在 Python 中表示为类文件对象sys.stdout
),print
也可以。
你真的想同时做这两个吗?如果是这样,您和wc
都将写入相同的标准输出。这就是你想要的吗?
@abarnert:我希望程序基本上编写 wc -l
正在获取的标准输入,所以是的,如果我理解你的问题,我想同时做这两个......意思是我想写信给wc -l
并实际调用wc -l
,所以不要像@Thomas 建议的那样只写标准输入。
@user248237 看看the subprocess
module。
在python中复制wc -l
的功能并不难。然后你就可以消除这个子流程的东西了。
【参考方案1】:
如果您想在外部通过管道将python
传递给wc
,这很简单,而且可以正常工作:
python myscript.py | wc -l
如果您想通过 tee 将其输出打印出来并通过管道传输到 wc
,请尝试 man tee
,或者更好的是,您的 shell 内置的精美重定向功能。
如果您希望在脚本中运行 wc -l
,并将您的输出发送到 stdout 和它,您也可以这样做。
首先,使用subprocess.Popen
启动wc -l
:
wc = subprocess.Popen(['wc', '-l'], stdin=subprocess.PIPE)
现在,你可以这样做了:
# write file line by line
with open("myfile") as f:
for line in f:
stripped = line.strip()
wc.stdin.write(stripped + '\n')
这将使wc
的输出与您的脚本位于同一位置。如果这不是您想要的,您也可以将其 stdout
设为 PIPE。在这种情况下,您希望使用communicate
,而不是尝试手动获取所有繁琐的细节。
【讨论】:
我想将wc
的输出重定向到一个文件。在那种情况下,我可以在Popen
中传递stdout=filehandle
对吗?
@user248237:没错。如果你想调用sort
,将它传送到grep
,然后将它传送到wc
,然后将它定向到一个文件……参见docs.python.org/2/library/…。但是,如果您经常这样做,您可能需要考虑在 PyPI 中使用许多更高级别的类似 shell 的库之一,或者只使用 bash 而不是 Python。
是的,你应该在完成后wc.wait()
。对于一个又快又脏的脚本,你可以直接退出,但在一个真正的程序中,你总是想要wait
(或communicate
或其他等价物)。
true 但手册说如果您将 stdout/stderr 设置为 PIPE
然后等待将挂起,所以我猜在这种情况下您不会调用它?改为调用通信?
@user248237:但是你没有将stdout
设置为PIPE
,你把它设置为一个文件描述符,对吧?您将stdin
设置为PIPE
,但这并不重要。 (当然有一些方法可以让stdin=PIPE
陷入僵局——或者即使没有它,你也可以在孩子身上编写代码等待你做某事,而不是那样做,然后阻塞wait
……但这不是该警告是关于。)以上是关于在 Python 中逐行写入管道的正确方法的主要内容,如果未能解决你的问题,请参考以下文章
C ++在循环中逐行写入文件或添加到数组并在循环后写入文件?
用python从符合一定格式的txt文档中逐行读取数据并按一定规则写入excel(openpyxl支持Excel 2007 .xlsx格式)
Objective C - 创建文本文件以在 Cocoa 中逐行读取和写入