使用os.system()时出现sed命令问题
我正在写一个小方法,用来替换文件中的一些文本。
我只需要一个参数,就是新的文本,因为要替换的文件和文本总是一样的。
我在使用 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)
但是,如果我尝试像下面这样把字符串作为参数传入,命令就没有执行。
我打印出来检查命令是否正确,确实是正确的。如果我把它复制粘贴到我的命令行中执行,也能成功。
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)
有没有人知道哪里出了问题?
谢谢
7 个回答
2
可能是缩进的问题?
下面的代码可以正常运行:
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
)当作变量名使用。
2
为了帮助你调试,可以试着添加:
print repr(cmd)
可能是一些特殊字符在你复制粘贴命令时混进来了,而普通的打印功能没有显示出来。
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,这个ID可以包含空格、引号等字符。文件名也可以传给这个函数,并且同样可以包含空格和其他一些特殊字符。这是因为你不需要额外启动一个命令行进程,所以在你的操作系统上启动的进程会少一个,你也不需要担心如何处理特殊的命令行字符。
还有一个选择:不要启动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'))
不需要新的进程。