nipy
nipy

Reputation: 5488

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.

Upvotes: 0

Views: 60

Answers (3)

Moses Koledoye
Moses Koledoye

Reputation: 78546

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

Upvotes: 1

don_aj
don_aj

Reputation: 11

If you are running a Linux distro, then you can use awk command and pipe it with grep.

If you want a solution with python, then the complexity is going to be O(n.m), where n is the number of lines in first file and m is the number of lines in second file.

Algorithm in python:

open a new file, file3
file1 = f.open(path to file 1)
n = number of lines in file1
file2 = f.open(path to file 2)
m = number of lines in file 2
for i in range(n):
   r = readline(file1)
   copy line into file3
   convert r to array and check to see if r[0] is "rserver"
   if r[0]=="rserver" then:
      for j in range(m):
         k = readline(file2)
         convert k to array and check to see if k[0] is "rserver"
         if k[0]=="rserver" then:
            merge required number of lines from file2 into file3
            increment j by x
close all files

Hope this helps!

Upvotes: 0

Craig Burgler
Craig Burgler

Reputation: 1779

The idea is to write a custom parser/translator like the following:

replacements = {}
with open('file2.txt') as f:
    for l in f:
        l = l.strip()
        if l.startswith('rserver'):
            server_header = l
            server = l.split()
            server_name = server[2]
        elif 'ip address' in l:
            ip_address = l
        elif 'service' in l:
            service = l
            replacements[server_name] = (server_header, ip_address, service)

with open('file1.txt') as f, open('out.txt', 'w') as out:
    for l in f:
        l = l.rstrip()
        if 'rserver' in l:
            server = l.split()
            server_name = server[1]
            out.write(l + '\n')
            out.write('  ' + replacements[server_name][0] + '\n')
            out.write('    ' + replacements[server_name][1] + '\n')
            out.write('    ' + replacements[server_name][2] + '\n')                
        else:
            out.write(l + '\n')

Output (out.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

Upvotes: 1

Related Questions