我正在编写一个小方法来替换文件中的某些文本。 我需要的唯一参数是新文本,因为它总是与要替换的文件和文本相同。
当我尝试使用方法的参数时,我在使用os.system()调用时遇到问题
如果我使用如下字符串,一切运行正常:
stringId = "GRRRRRRRRR"
cmd="sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=" + stringId + "/g' path/file.old > path/file.new"
os.system(cmd)
现在,如果我尝试将字符串作为下面的参数,则不执行该命令。 我做了一个打印,看看命令是否正确,它是。如果我复制/粘贴到我的shell
,我甚至可以成功执行它import os
def updateExportConfigId(id):
stringId = "%s" % id
cmd= "sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=" + stringId + "/g' path/file.old > path/file.new"
print "command is " + cmd
os.system(cmd)
有谁知道出了什么问题?
由于
答案 0 :(得分:5)
强制性:不使用os.system
- 使用subprocess
模块:
import subprocess
def updateExportConfigId(m_id, source='path/file.old',
destination='path/file.new'):
if isinstance(m_id, unicode):
m_id = m_id.encode('utf-8')
cmd= [
"sed",
",$s/MANAGER_ID=[0-9]*/MANAGER_ID=%s/g" % m_id,
source,
]
subprocess.call(cmd, stdout=open(destination, 'w'))
使用此代码可以传递管理员ID,它可以包含空格,引用字符等。文件名也可以传递给函数,也可以包含空格和其他一些特殊字符。那是因为你的shell没有被不必要地调用,所以在你的操作系统上启动了少一个进程,你不必担心转义特殊的shell字符。
另一种选择:不要启动sed。使用python的re
模块。
import re
def updateExportConfigID(m_id, source, destination):
if isinstance(m_id, unicode):
m_id = m_id.encode('utf-8')
for line in source:
new_line = re.sub(r'MANAGER_ID=\d*',
r'MANAGER_ID=' + re.escape(m_id),
line)
destination.write(new_line)
并将其称为:
updateExportConfigID('GRRRR', open('path/file.old'), open('path/file.new', 'w'))
无需新流程。
答案 1 :(得分:2)
为了帮助您调试它,请尝试添加:
print repr(cmd)
当您复制并粘贴普通打印件时,可能会出现一些特殊字符滑入命令。
答案 2 :(得分:1)
错误的是存在一些差异。是的,我知道这没有用,但你需要找出差异。
尝试运行:
import os
def updateExportConfigId(id):
stringId = "%s" % id
cmd1 = "sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=" + stringId + "/g' path/file.old > path/file.new"
stringId = "GRRRRRRRRR"
cmd2 = "sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=" + stringId + "/g' path/file.old > path/file.new"
print "cmd1:" , cmd1
print "cmd2:" , cmd2
print cmd1 == cmd2
updateExportConfigId("GRRRRRRRRR")
代码应打印:
sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=GRRRRRRRRR/g' path/file.old > path/file.new
sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=GRRRRRRRRR/g' path/file.old > path/file.new
True
从而表明它们完全相同。如果最后一行是“假”,那么它们就不一样了,你应该能够看到差异。
答案 3 :(得分:1)
因此,从以前的答案我们现在知道id
是一个Unicode字符串,它使cmd1成为一个Unicode字符串,os.system()将其转换为字节字符串,以便以默认编码执行。
a)我建议使用subprocess而不是os.system()
b)我建议不要将内置函数的名称用作变量(id
)。
c)我建议在执行之前将字符串显式编码为字节字符串:
if isinstance(cmd,unicode):
cmd = cmd.encode("UTF-8")
d)对于Lennart Regebro的建议,添加:
assert type(cmd1) == type(cmd2)
后
print cmd1 == cmd2
答案 4 :(得分:0)
也许有一些缩进问题?
以下工作正常:
import os
def updateExportConfigId(id):
stringId = "%s" % id
cmd= "sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=" + stringId + "/g' test.dat > test.new"
print "command is " + cmd
os.system(cmd)
updateExportConfigId("adsf")
也不要使用保留字(id
)作为变量。
答案 5 :(得分:0)
仅使用raw strings可能会有所帮助。
答案 6 :(得分:0)
最后,我找到了运行os.system(cmd)的方法!
简单的技巧,“清理”cmd字符串:
os.system(str(cmd))
现在,我能够使用我需要的所有参数构建cmd,最后我使用str()调用“清理”它,然后使用os.system()调用运行它。
非常感谢您的回答!
SWON