从python调用grep命令

2024-03-29 11:20:36 发布

您现在位置:Python中文网/ 问答频道 /正文

平台:Windows

格雷普:http://gnuwin32.sourceforge.net/packages/grep.htm

Python:2.7.2

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

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

abcd    2345

2345

abcd    2345$

grep "2345$" file.txt

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

当我试图通过python运行上面的命令时,我看不到任何输出。 Python代码片段如下:

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命令使用"

grep_cmd.extend([grep, '"2345$"' ,temp.name])

从python执行失败。python不应该执行 命令就是这样。

谢谢 古奇。


Tags: 文件name命令txtcmdwindowstempgrep
1条回答
网友
1楼 · 发布于 2024-03-29 11:20:36

不要在你的图案上加双引号。只需要在命令行中引用shell元字符。从python调用程序时,不需要这样做。

你也不需要自己打开文件-grep会这样做:

grep_cmd.extend([grep, '2345$', 'file.txt'])

要了解不需要双引号的原因并导致命令失败,需要了解双引号的用途以及如何处理它们。

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

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

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

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

python子进程模块页面中有这样一个关于shell=True和Windows的内容:

On Windows: the Popen class uses CreateProcess() to execute the child child program, which operates on strings. If args is a sequence, it will be converted to a string in a manner described in Converting an argument sequence to a string on Windows.

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

args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names).

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

我想如果你叫subprocess.Popen就像:

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

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

相关问题 更多 >