从python调用grep命令

从python调用grep命令,python,grep,Python,Grep,平台:Windows 格雷普: Python:2.7.2 用于执行命令的Windows命令提示符 我正在文件中搜索以下模式“2345$”。 文件内容如下: abcd 2345 2345 abcd 2345$ temp = open('file.txt', "r+") grep_cmd = [] grep_cmd.extend([grep, '"2345$"' ,temp.name]) print grep_cmd p = subprocess.Popen(grep_cmd,

平台:Windows

格雷普:

Python:2.7.2

用于执行命令的Windows命令提示符

我正在文件中搜索以下模式
“2345$”
。 文件内容如下:

abcd    2345

2345

abcd    2345$
temp = open('file.txt', "r+")
grep_cmd = []
grep_cmd.extend([grep, '"2345$"' ,temp.name])
print grep_cmd
p = subprocess.Popen(grep_cmd, 
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)
stdoutdata = p.communicate()[0]
print stdoutdata
grep“2345$”file.txt

grep成功返回两行(第一行和第二行)

当我试图通过python运行上述命令时,我没有看到任何输出。 Python代码片段如下所示:

abcd    2345

2345

abcd    2345$
temp = open('file.txt', "r+")
grep_cmd = []
grep_cmd.extend([grep, '"2345$"' ,temp.name])
print grep_cmd
p = subprocess.Popen(grep_cmd, 
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)
stdoutdata = p.communicate()[0]
print stdoutdata
如果我有

grep_cmd.extend([grep, '2345$' ,temp.name])
在我的python脚本中,我得到了正确的答案

问题是为什么grep命令使用

从python执行失败。python不应该执行吗 命令的原样

谢谢
Gudge.

不要在模式周围加双引号。只需要在命令行上加上shell元字符的引号。从python调用程序时,不需要这样做

您也不需要自己打开文件-grep将执行以下操作:

grep_cmd.extend([grep, '2345$', 'file.txt'])
要了解不需要双引号并导致命令失败的原因,您需要了解双引号的用途及其处理方式

shell使用双引号防止对某些shell元字符进行特殊处理。shell元字符是shell专门处理的字符,不会直接传递给它执行的程序。最常用的shell元字符是“空格”“。shell在空间边界上拆分一个命令,以构建一个参数向量来执行程序。如果要在参数中包含空格,则必须以某种方式将其引用(单引号或双引号、反斜杠等)。另一个是美元符号($),用于表示变量扩展

当您在没有涉及shell的情况下执行程序时,所有这些关于引用和shell元字符的规则都是不相关的。在python中,您自己构建参数向量,因此相关的引用规则是python引用规则(例如,要在双引号字符串中包含双引号,请在双引号前面加一个反斜杠-反斜杠不会出现在最后一个字符串中)。完成构造参数向量时,参数向量的每个元素中的字符都是将传递给正在执行的程序的文字字符

Grep不会将双引号视为特殊字符,因此如果Grep在其搜索模式中获得双引号,它将尝试从输入中匹配双引号

我最初的回答中提到的
shell=True
是不正确的-首先,我没有注意到您最初指定了
shell=True
,其次,我是从Unix/Linux实现的角度出发的,而不是从Windows

python子流程模块页面中有这样一句话,关于
shell=True
和Windows:

在Windows上:Popen类使用CreateProcess()执行子程序,该程序对字符串进行操作。如果args是一个序列,它将按照中所述的方式转换为字符串

关于在Windows上将参数序列转换为字符串的链接部分对我来说毫无意义。首先,字符串是一个序列,列表也是一个序列,但“常用参数”部分对参数作了如下说明:

所有调用都需要args,args应该是字符串或程序参数序列。通常首选提供一系列参数,因为它允许模块处理任何必需的参数转义和引用(例如,允许文件名中有空格)

这与Python文档中描述的转换过程相矛盾,鉴于您观察到的行为,我认为文档是错误的,只应用于参数字符串,而不是参数向量。我自己无法验证这一点,因为我没有Windows或Python的源代码

我怀疑如果调用
subprocess.Popen
如下:

p = subprocess.Popen(grep + ' "2345$" file.txt', stdout=..., shell_True)

您可能会发现,双引号作为有文档记录的参数转换的一部分被去掉。

您可以使用python-textops3:

from textops import *

print('\n'.join(cat('file.txt') | grep('2345$')))
使用python-textops3,您可以在python中的管道中使用类unix命令


所以不需要叉一个非常重的进程,因为没有直接回答问题,但是有没有什么原因不想用python手动“grep”文件?例如,通过使用re?这将是更少的行…我知道我可以做一个搜索。它的具体要求是通过python.ok,fair-ough@gudge执行命令。别误会我的意思,我只是想确保你知道你在做什么:)没有双引号,它就可以工作了。但它不应该也适用于双引号吗。如果我没有错的话,Python应该按原样选择数组的内容。如果是这种情况,那么通过python执行的grep命令(带双引号)应该返回这两行。@grudge:当您将双引号放在单引号内时,双引号将成为模式的一部分。显然,您的文件中没有引号,因此不匹配。请记住,当您从命令行调用grep时,shell会在grep看到引号之前将其删除。gudge:我已经更新了我的答案,以扩展参数的处理方式,并对可能直接导致您混淆的错误进行评论。