1

Here is my code I want to search and replace three strings

tmp="/tmp"
day = datetime.date.today().day
today = datetime.date.today()
year =datetime.date.today().year
month = today.strftime('%b')

f1 = open("%s/backup.txt" % (tmp), 'r')
f2 = open("%s/backup1.txt" % (tmp), 'w')
for line in f1:
      f2.write(line.replace('day',  "%s" % (day)))
f1.close()
f2.close()

f1 = open("%s/backup1.txt" % (tmp), 'r')
f2 = open("%s/backup2.txt" % (tmp), 'w')
for line in f1:
      f2.write(line.replace('mon',  "%s" % (mon)))
f1.close()
f2.close()

f1 = open("%s/backup2.txt" % (tmp), 'r')
f2 = open("%s/backup3.txt" % (tmp), 'w')
for line in f1:
      f2.write(line.replace('year',  "%s" % (year)))
f1.close()
f2.close()

Anyway to do this in a single shot and by reducing the LOC?

I want to search and replace year, mon and day in single shot Regards,

tobias_k
  • 81,265
  • 12
  • 120
  • 179
user4432340
  • 15
  • 1
  • 6

2 Answers2

3

You can just do the three replacements in the same loop, before writing the line to the new file.

f1 = open("%s/backup.txt" % (tmp), 'r')
f2 = open("%s/backup1.txt" % (tmp), 'w')
for line in f1:
    new_line = line.replace('day',  "%s" % (day))
    new_line = line.replace('mon',  "%s" % (mon))
    new_line = line.replace('year',  "%s" % (year))
    f2.write(new_line)
f1.close()
f2.close()

You could even do all three on the same line, if you prefer, though that line would be very long and should be broken with \ anyway. Also, you can (and should) use with to open and close files.

with open("%s/backup.txt"  % tmp, 'r') as f1, \
     open("%s/backup1.txt" % tmp, 'w') as f2:
    for line in f1:
        new_line = line.replace('day',  "%s" % day) \
                       .replace('mon',  "%s" % mon) \
                       .replace('year', "%s" % year)
        f2.write(new_line)

Building upon the idea by @bruno, you could also create a dictionary with replacements and then use regular expression to find "day" or "mon" or "year" "day|mon|year" and replace it with the value from the dict.

>>> day, mon, year = 2017, 5, 15
>>> repl = {"day": day, "mon": mon, "year": year}
>>> line = "test string with day, mon, and year in it"
>>> re.sub("day|mon|year", lambda m: str(repl.get(m.group())), line)
'test string with 2017, 5, and 15 in it'

Even better: If you have control over the template file, you can just wrap the parts to be replaced into {...} and then use str.format for the replacement (assuming that {...} do not appear otherwise in the file).

>>> line = "test string with {day}, {mon}, and {year} in it"
>>> line.format(**repl)
'test string with 2017, 5, and 15 in it'
Community
  • 1
  • 1
tobias_k
  • 81,265
  • 12
  • 120
  • 179
2
tmp="/tmp"
today = datetime.date.today()
day = "%s" % today.day
year = "%s" % today.year
month = today.strftime('%b')

replacements = [
    # find -> replace
    ('day', day),
    ('mon', mon),
    ('year', year)
    ]


with open("%s/backup.txt" % (tmp), 'r') as source, \
   open("%s/backup1.txt" % (tmp), 'w') as dest:

    for line in source:
        for target, replacement in replacements:
            line = line.replace(target, replacement) 
      dest.write(line)
bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • Hi Bruno Desthuilliers, I'm getting line = line.replace(target, replacement) TypeError: expected a character buffer object error. – user4432340 May 15 '17 at 10:08
  • @user4432340 You probably forgot to convert to `str`; bruno is doing this when declaring `day`, `month` etc (but you could also do so in the dict or in `line.replace`) – tobias_k May 15 '17 at 10:34
  • @tobias_k Thanks a lot Sir. I got it. – user4432340 May 17 '17 at 09:15