2

I have a text file that I needs to manipulate. I want to add a line after occurence of word "exactarch". Means whenever "exactarch" occurs, I want to add text in the next line.

E.g. If this is the original file content,

[main]
cachedir=/var/cache/yum
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
distroverpkg=redhat-release
tolerant=1
exactarch=1
gpgcheck=1
plugins=1

I want to change it as below:

[main]
cachedir=/var/cache/yum
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
distroverpkg=redhat-release
tolerant=1
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1

This is what I tried to do:

with open('file1.txt') as f:
    for line in input_data:
        if line.strip() == 'exactarch':  
            f.write('obsoletes=1')

Obviously this is not working as I can't figure out how can I count and write to this line.

Abhishek dot py
  • 909
  • 3
  • 15
  • 31

4 Answers4

4

You ask for a Python solution. But tasks like this are made to be solved using simpler tools.

If you are using a system that has sed, you can do this in a simle one-liner:

$ sed '/exactarch/aobsoletes=1' < in.txt

What does this mean?

  • sed: the executable
  • /exactarch/: matches all lines that contain exactarch
  • a: after the current line, append a new line with the following text
  • obsoletes=1: the text to append in a new line

Output:

[main]
cachedir=/var/cache/yum
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
distroverpkg=redhat-release
tolerant=1
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1

Edit:

To modify the file in place, use the option -i and the file as an argument:

$ sed -i '/exactarch/aobsoletes=1' in.txt
3

Simple - read all lines, find correct line and insert desired line after found. Dump result lines to file.

import os 
with open('lines.txt') as f:
    lines = f.readlines()

lines.insert(lines.index('exactarch=1\n') + 1, 'obsoletes=1\n')
with open('dst.txt', 'w') as f:
    for l in lines:
        f.write(l)
Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
2

The past says it's pretty simple - replacing words in files is not a new thing.

If you want to replace a word, you can use the solution implemented there. In your context:

import fileinput

for line in fileinput.input(fileToSearch, inplace=True):
    print(line.replace("exactarch", "exactarch\nobsoletes=1"), end='')
Community
  • 1
  • 1
A. Abramov
  • 1,823
  • 17
  • 45
0

I am hesitant using fileinput, b/c if something goes wrong during the 'analysis' phase you are left with a file in whatever conditions it was left before the failure. I would read everything in, and then do full work on it. The code below ensures that:

  • Your inserted value contains a newline value '\n' if it's not going to be the last item.
  • Will not add duplicate inserted values by checking the one below it.
  • Iterates through all values incase multiple "exactarch=1"s were added since the snippet last ran.

Hope this helps, albeit not as stylish as a one/two liner.

with open('test.txt') as f:
    data = f.readlines()

insertValue = 'obsoletes=1'

for item in data:
    if item.rstrip() == 'exactarch=1': #find it if it's in the middle or the last line (ie. no '\n')
        point = data.index(item)

        if point+1 == len(data): #Will be inserted as new line since current exactarch=1 is in last position, so you don't want the '\n', right?
            data.insert(point+1, instertValue)
        else:
            if data[point + 1].rstrip() != insertValue: #make sure the value isn't already below exactarch=1
                data.insert(point+1, insertValue + '\n')
                print('insertValue added below "exactarch=1"')
            else:
                print('insertValue already exists below exactarch=1')

with open('test.txt','w') as f:
    f.writelines(data)
Miles
  • 1,104
  • 11
  • 13