Python子进程grep命令每次返回的结果不同
我正在尝试在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模块让它正常工作,但结果都是一样的问题。
为了说明情况,我直接在命令行中测试了我的grep命令,效果很好。这是我传递给函数的cmd参数:
['egrep', '-wi', '-nr', "'keyword1|keyword2|blabla'", 'test/match_inside.txt']
我还尝试过使用不同的bufsize值(当然也试过不设置值)。
2 个回答
1
我不能评论,但我忍不住想问:
为什么要在Python里面运行grep
呢?而且还用到subprocess?如果你已经在用Python,我强烈建议你看看Python的正则表达式。总的来说,它比grep强大得多,而且我觉得更容易理解和控制。
补充:这个问题是实际的。我想知道原因。
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),所以参数不需要用引号括起来;参数的结构和分组是由这个字符串数组来创建的。
当你在python中使用
"'keyword1|keyword2|blabla'"
时,你实际上是将
'keyword1|keyword2|blabla'
作为完整的字符串传递给grep,而你其实只想让grep接收到
keyword1|keyword2|blabla
作为argv中索引3的字符串(具体取决于前面参数的数量)。