【问题标题】:How to use subprocess and 'cat' to read in data line by line?如何使用子进程和'cat'逐行读取数据?
【发布时间】:2017-02-13 07:52:38
【问题描述】:

我无法理解如何使用subprocess 解决我的问题。

假设我的子目录中有一个制表符分隔的文本文件tabdelimited1.txt,我想将其读入熊猫数据框。

当然,您可以按如下方式简单地导入数据:

import pandas as pd
df = pd.read_csv("tabdelimited1.txt", header=None, sep="\s+")

但是,假设我们想使用subprocess。在命令行中,$cat tabdelimited1.txt 将输出所有行。

现在,我想使用子进程来读取cat tabdelimited1.txt 的输出。如何做到这一点?

我们可以使用

import subprocess
task = subprocess.Popen("cat file.txt", shell=True,  stdout=subprocess.PIPE)
data = task.stdout.read()

但是 (1) 我收到 shell=True 的错误和 (2) 我想逐行读取数据。

如何使用subprocess 逐行读取tabdelimited1.txt?脚本应如下所示:

import subprocess
import pandas as pd

df = pd.DataFrame()
task = subprocess.Popen("cat file.txt", shell=True,  stdout=subprocess.PIPE)
# while lines exist:
    # line = subprocess std
    df=pd.concat([df, line])

已编辑

【问题讨论】:

  • shell=True 出现什么错误?
  • 子进程模块与从管道输入中读取无关,您只需要read from sys.stdin for cat x.txt | python script1.py
  • @TessellatingHeckler 但 OP 想使用 subprocess
  • @tdelaney OP 想要使用 subprocess 从管道输入中读取,这没有意义。一种可能的前进方式是“如何使用 subprocess 调用 cat 来读取文件”,但另一种前进方式是“为什么你不需要使用 subprocess 来做你想做的事情在问题的最后描述您认为子流程将启用(但不会)“.
  • 最后cat...| ...script1.py 行的目的是什么? script1.py is already doing a cat file.txt. It's not reading from stdin`(这是外部cat 将其输出传送到的位置。

标签: python python-3.x csv subprocess cat


【解决方案1】:

您可以通过将命令分解为列表来完全跳过 shell。那么它只是迭代流程标准输出的问题:

import subprocess
import pandas as pd

df = pd.DataFrame()
task = subprocess.Popen(["cat", "file.txt"], stdout=subprocess.PIPE)
for line in task.stdout:
    df=pd.concat([df, line])
task.wait()

【讨论】:

  • 您能解释一下for line in task.stdouttask.wait() 的工作原理吗? task.stdout 是一个包含cat file.txt 全部内容的变量?
  • 这个版本和 OP shell=True 版本都适合我。
  • task.stdout 就像sys.stdout 和任何打开的文件;迭代它会逐行读取。
  • 当您说stdout=subprocess.PIPE 时,Popen 将为进程标准输出创建一个管道并将其设置在变量stdout 中。因此,它是一个将读取子输出的文件对象。
【解决方案2】:
import sys
for line in sys.stdin:
    print(line.split())

可以与 shell 命令一起使用,例如:

0025:~/mypy$ cat x.txt | python3 stack39864304.py
['1', '3', 'test1;']
['2', '2', 'test2;']
['3', '2', 'test3;']

否则在交互式会话中我可以这样做:

In [269]: task = subprocess.Popen("cat x.txt", shell=True,  stdout=subprocess.PIPE)
In [270]: for line in task1.stdout:print(line.split())
[b'1', b'3', b'test1;']
[b'2', b'2', b'test2;']
[b'3', b'2', b'test3;']

(py3 字节串)

python3 stack39864304.py < x.txt 是将此文件发送到脚本的另一种方式。

cat afile | ... 可能太简单了,并提出所有关于为什么不直接阅读的反对意见。但是cat 可以替换为headtail 甚至ls -l | python3 stack39864304.py 以获取带有此split 的目录列表。

我的大部分交互式 python 编码都使用ipython;它的许多%magic 使用子流程;我在本次会议中一直使用cat x.txtls

【讨论】:

  • 所以,sys.stdin 需要一个命令 cat x.txt。与使用task = subprocess.Popen()相比,还有其他区别(例如性能等)吗?
  • stdin 从管道读取或< x.txt 文件重定向(在 linux 中)。您不必选择一种方法而不是其他方法。学会全部使用它们。
  • 谢谢---顺便说一句,我不知道你为什么在上面被否决---我当然感谢你的回应和贡献
猜你喜欢
  • 1970-01-01
  • 2011-02-17
  • 2013-02-17
  • 2011-04-12
  • 2019-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多