在 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 中逐行读取和写入

delphi中怎么逐行读取文本文件的数据并将每行分别写入指定的不同编辑框

在Python中逐行读取多行字符串

Python从txt文件中逐行读取数据