您在这里使用了一些奇怪的语法:
for line in old_network: new_network.write(line) if not re.match(("HOSTNAME"), line)
for line in old_network: new_network.write(replacement) if re.match(("HOSTNAME"), line)
您需要在此处反转if
语句,并将它们放在单独的行中;您必须组合循环,这样您也可以简化if
语句:
for line in old_network:
if not re.match("HOSTNAME", line):
new_network.write(line)
else:
new_network.write(replacement)
你不能真正循环两次输入文件(你的第二个循环不会做任何事情,因为文件已经被完整读取)。
接下来,您想使用打开的文件对象上下文管理器(使用with
)确保它们正确关闭,无论发生什么。您可以从文件模式中删除+
,您没有在混合模式下使用文件,并且最好先完成备份副本,然后再打开任何内容进行读取和写入。
这里不需要使用正则表达式;您正在测试是否存在一个简单的简单字符串,会做,'HOSTNAME' in line
或者可能line.strip().startswith('HOSTNAME')
要确保该行以.HOSTNAME
使用该tempfile
模块创建一个名称不会冲突的临时文件:
from tempfile import NamedTemporaryFile
shutil.copyfile('/etc/sysconfig/network', '/etc/sysconfig/network.setup_bak')
replacement = "HOSTNAME={}\n".format(sys.argv[1])
new_network = NamedTemporaryFile(mode='w', delete=False)
with open("/etc/sysconfig/network", "r") as old_network, new_network:
for line in old_network:
if line.lstrip().startswith('HOSTNAME'):
line = replacement
new_network.write(line)
os.rename(new_network.name, "/etc/sysconfig/network")
print 'Hostname set to {}'.format(sys.argv[1])
fileinput
您可以通过使用该模块进一步简化此操作,该模块可让您通过简单的打印来替换文件内容;它支持本地创建备份文件:
import fileinput
import sys
replacement = "HOSTNAME={}\n".format(sys.argv[1])
for line in fileinput('/etc/sysconfig/network', inplace=True, backup='.setup_bak'):
if line.lstrip().startswith('HOSTNAME'):
line = replacement
sys.stdout.write(line)
print 'Hostname set to {}'.format(sys.argv[1])
那是 6 行代码(不计算导入)与您的 12 行代码。我们可以通过使用条件表达式将其压缩到仅 4 行,但我不确定这是否会使事情更具可读性:
for line in fileinput('/etc/sysconfig/network', inplace=True, backup='.setup_bak'):
sys.stdout.write(replacement if line.lstrip().startswith('HOSTNAME') else line)