0

我正在尝试从 Python 调用“sed”,并且无法通过 subprocess.check_call() 或 os.system() 传递命令行。

我在 Windows 7 上,但使用来自 Cygwin 的“sed”(它在路径中)。

如果我从 Cygwin shell 执行此操作,它可以正常工作:

$ sed 's/&amp;nbsp;/\&nbsp;/g' <"C:foobar" >"C:foobar.temp"

在 Python 中,我在“名称”中得到了我正在使用的完整路径名。我试过:

command = r"sed 's/&amp;nbsp;/\&nbsp;/g' " +  "<" '\"' + name + '\" >' '\"' + name + '.temp' + '\"'
subprocess.check_call(command, shell=True)

所有的连接都是为了确保我在输入和输出文件名周围有双引号(以防 Windows 文件路径中有空格)。

我还尝试将最后一行替换为:

os.system(command)

无论哪种方式,我都会收到此错误:

sed: -e expression #1, char 2: unterminated `s' command
'amp' is not recognized as an internal or external command,
operable program or batch file.
'nbsp' is not recognized as an internal or external command,
operable program or batch file.

然而,正如我所说,它在控制台上运行良好。我究竟做错了什么?

4

3 回答 3

5

subprocess 使用的 shell 可能不是您想要的 shell。您可以使用executable='path/to/executable'. 不同的shell有不同的引用规则。

更好的可能是subprocess完全跳过,并将其编写为纯 Python:

with open("c:foobar") as f_in:
    with open("c:foobar.temp", "w") as f_out:
        for line in f_in:
            f_out.write(line.replace('&amp;nbsp;', '&nbsp;'))
于 2012-07-24T01:52:41.197 回答
1

我想你会发现,在 Windows Python 中,它实际上并没有使用CygWin shell 来运行你的命令,而是使用cmd.exe.

而且,cmd单引号不能很好地发挥bash作用。

您只需执行以下操作即可确认:

c:\pax> echo hello >hello.txt

c:\pax> type "hello.txt"
hello

c:\pax> type 'hello.txt'
The system cannot find the file specified.

我认为最好的办法是使用 Python 本身来处理文件。Python 语言是一种跨平台语言,旨在消除所有平台特定的不一致,例如您刚刚发现的不一致。

于 2012-07-24T01:54:56.137 回答
1

我同意 Ned Batchelder 的评估,但考虑一下您可能想要考虑使用以下代码的原因,因为它可能会完成您最终想要完成的事情,这可以在 Pythonfileinput模块的帮助下轻松完成:

import fileinput

f = fileinput.input('C:foobar', inplace=1)
for line in f:
    line = line.replace('&amp;nbsp;', '&nbsp;')
    print line,
f.close()
print 'done'

这将根据关键字的使用有效地更新给定文件。还有一个可选backup=关键字——上面没有使用——如果需要,它将保存原始文件的副本。

顺便说一句,关于使用诸如C:foobar指定文件名之类的东西要小心,因为在 Windows 上,这意味着该名称的文件位于驱动器 C: 上的任何当前目录中,这可能不是您想要的。

于 2012-07-24T02:52:38.483 回答