我正在尝试从Python调用'sed'并且遇到麻烦通过subprocess.check_call()或os.system()传递命令行。
我在Windows 7上,但使用Cygwin的'sed'(它在路径中)。
如果我从Cygwin shell中执行此操作,它可以正常工作:
$ sed 's/&nbsp;/\ /g' <"C:foobar" >"C:foobar.temp"
在Python中,我已经获得了我在“name”中使用的完整路径名。我试过了:
command = r"sed 's/&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.
然而,正如我所说,它可以在控制台上正常工作。我究竟做错了什么?
答案 0 :(得分:5)
子进程使用的shell可能不是您想要的shell。您可以使用executable='path/to/executable'
指定shell。不同的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('&nbsp;', ' '))
答案 1 :(得分: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语言是一种跨平台语言,旨在删除所有那些特定于平台的不一致性,例如您刚刚找到的那种。
答案 2 :(得分:1)
我同意Ned Batchelder的assessment,但想想你可能想要考虑使用下面的代码,因为它可能会做你最终想要完成的事情,这可以通过Python {{1}的帮助轻松完成} module:
fileinput
这将使用关键字建议有效地更新给定文件。还有一个可选的import fileinput
f = fileinput.input('C:foobar', inplace=1)
for line in f:
line = line.replace('&nbsp;', ' ')
print line,
f.close()
print 'done'
关键字 - 上面未使用 - 如果需要,它会保存原始文件的副本。
backup=
之类的东西来指定文件名的警告,因为在Windows上它意味着当前目录在驱动器C:上的那个名称的文件,这可能不是你的想。