adele adele - 3 months ago 11
Python Question

Appending data with additional information to text in a file

I have a text file containing thousands of lines of code and I would like to replace certain elements as follows:

Text from file1:

serverfarm host foobar2:443
failaction reassign
probe tcp111-probe
rserver foobar1 443
rserver foobar2 443


Text with additional information that I would like to append to original file text (file2):

rserver host foobar1
ip address 1.1.1.1
inservice
rserver host foobar2
ip address 1.1.1.2
inservice


So we can see that in the original file the
rserver
line does not capture the IP address but I have this information in the other file.

Before:

rserver foobar1 443


After (desired output)

rserver foobar1 443
<--- Keep original text

rserver host foobar1
<--- This and following two lines should be added below original text

ip address 1.1.1.1

inservice


There is a direct mapping between the original text string
"rserver foobar1 443"
(remove 3rd text block) and the first line of the replacement text
"rserver host foobar1"
(remove 2nd text block = host).

Is it possible to do this with a python dictionary or similar approach? I would appreciate it if someone could show me how to do this in Python and I will then use this approach when doing similar tasks.

Answer

Yes, you can use a dictionary or defaultdict to map server names from the second file and their list of details (ip and service status) and insert these details while writing into a new file:

from collections import defaultdict
import re

d = defaultdict(list)
with open('file1.txt') as f1, open('file2.txt') as f2, open('output.txt', 'w') as f3:
    for line in f2:
        if 'host' in line:
            key = line.strip().replace('host ', '')
        d[key].append('  ' + line) # match indentation in file1 with leading spaces

    for line in f1:
        f3.write(line if '\n' in line else line+'\n')
        if 'rserver' in line:
            f3.writelines(d[re.sub(r'\s\d+', '', line.strip())])

output.txt:

serverfarm host foobar2:443
  failaction reassign
  probe tcp111-probe
  rserver foobar1 443
  rserver host foobar1
    ip address 1.1.1.1
    inservice
  rserver foobar2 443
  rserver host foobar2
    ip address 1.1.1.2
    inservice