Reputation: 5488
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
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
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
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