1

我正在尝试使用以下代码在带有 python 的文件上启动 grep:

def runProcess(self, cmd):
    p = subprocess.Popen(cmd, bufsize=16000, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    return iter(p.stdout.readline, b'')

问题是我每次启动它时都会得到不同的匹配。一些行在返回对象中被简单地跳过。就像缓冲区已被覆盖一样。我已经尝试了我在 subprocess 中找到的所有方法来完成这项工作,但都导致了同样的问题。

有关信息,我已经直接在 shell 中测试了我的 grep 命令并且它运行良好,这是我作为 cmd 参数传递给我的函数的内容

['egrep', '-wi', '-nr', "'keyword1|keyword2|blabla'", 'test/match_inside.txt']

我也尝试过使用不同的 bufsize 值(并且没有 c 值)

4

2 回答 2

2

当您改为调用时,问题就消失了(在我的测试中):

['egrep', '-wi', '-nr', 'keyword1|keyword2|blabla', 'test/match_inside.txt']

Popen的文档表明 shlex.split() 演示了如何将命令行参数转换为字符串列表。在他们的示例中,外部引号从单个参数中删除。

编辑:我们对 bash 的熟悉可能会误导我们。但是 Bash 只是另一种脚本语言。如果你输入

grep 'a|b|c' target.txt

bash 正在调用操作系统调用(Linux 上的 exec 或某些变体)来创建新的 grep 进程。Bash 解析该命令并删除引号;它们不是 grep 选项的一部分,它们可以通过对标记进行分组来帮助 bash 扫描您的输入。Grep 将被传递一个字符串数组参数(这就是 C 中的 argv ),因此参数不需要括在引号中;参数的结构和分组由字符串数组创建。

当你使用

"'keyword1|keyword2|blabla'"

在 python 中,你基本上是在传递

'keyword1|keyword2|blabla'

把 grep 作为完整的字符串,当你真的只想 grep 有

keyword1|keyword2|blabla

作为 argv 的索引 3 中的字符串(取决于前面 args 的数量)。

于 2013-03-14T21:11:29.017 回答
1

我无法发表评论,但我无法阻止自己问:

为什么要grep在 Python 中运行?和子进程??如果您使用的是Python,那么我强烈建议您阅读Python RE。它比 grep 强大得多,总而言之(在我看来)更易于理解和控制。

编辑:这个问题是务实的。我想知道为什么。

于 2013-03-14T21:13:09.380 回答