python - concision in a for loop without list comprehension -
please don't laugh. i'm trying write simple script replace hostname , ip of base vm. have working version of this, i'm trying make more readable , concise. i'm getting syntax error when trying code below. trying make these list comprehensions, since file types, won't work. in advance.
try: old_network = open("/etc/sysconfig/network", "r+") new_network = open("/tmp/network", "w+") replacement = "hostname=" + str(sys.argv[1]) + "\n" shutil.copyfile('/etc/sysconfig/network', '/etc/sysconfig/network.setup_bak') line in old_network: new_network.write(line) if not re.match(("hostname"), line) line in old_network: new_network.write(replacement) if re.match(("hostname"), line) os.rename("/tmp/network","/etc/sysconfig/network") print 'hostname set to', str(sys.argv[1]) except ioerror, e: print "error %s" % e pass
you using odd syntax here:
for line in old_network: new_network.write(line) if not re.match(("hostname"), line) line in old_network: new_network.write(replacement) if re.match(("hostname"), line)
you need reverse if
statement there, , put these on separate lines; have combine loops, lets simplify if
statements too:
for line in old_network: if not re.match("hostname", line): new_network.write(line) else: new_network.write(replacement)
you cannot loop on input file twice (your second loop wouldn't file has been read in full).
next, want use open file objects context managers (using with
) make sure closed properly, whatever happens. can drop +
file modes, not using files in mixed mode, , backup copy best done first before opening reading , writing yet.
there no need use regular expression here; testing presence of straightforward simple string, 'hostname' in line
do, or perhaps line.strip().startswith('hostname')
make sure line starts hostname
.
use tempfile
module create temporary file name won't conflict:
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) open("/etc/sysconfig/network", "r") old_network, new_network: 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 {}'.format(sys.argv[1])
you can simplify further using fileinput
module, lets replace file contents printing; supports creating backup file natively:
import fileinput import sys replacement = "hostname={}\n".format(sys.argv[1]) 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 {}'.format(sys.argv[1])
that's 6 lines of code (not counting imports) versus 12. can squash down 4 using conditional expression, not sure if makes things more readable:
for line in fileinput('/etc/sysconfig/network', inplace=true, backup='.setup_bak'): sys.stdout.write(replacement if line.lstrip().startswith('hostname') else line)
Comments
Post a Comment