TAGS :Viewed: 7 - Published at: a few seconds ago

[ inserting a line in a file using python ]

I have a file which contains data like this:

$ yum -- to install package
admin1,group,n,0123456,/usr/bin 
user2,group,n,0123456,/usr/bin
group,n,0123456,/usr/bin
----->#i have to insert a new line here
$cat -- to read contents of a file
admin1,group,n,0123456,/usr/bin
user2,group,n,0123456,/usr/bin
group,n,0123456,/usr/bin

First, I have to find the the word $ yum in the file and insert a new line before starting of the next word starting with $.

Some help with my code would be appreciated.

 with open("test.txt", "a") as myfile:
      for row in myfile:
            if re.match(r'$yum,i): 
                myfile.append("user2,group,0123456,/usr/bin") 

Answer 1


Opening the file with a does not allow you to file_object.append(..., it means when you write to the file content will be added to the end of the file so myfile.append("user2,group,0123456,/usr/bin") is not remotely valid syntax.

You can use itertools.groupby to group by section where lines start with a $, then either add a line if the line starts with $ yum or just write the lines as is:

from itertools import groupby
from tempfile import NamedTemporaryFile
from shutil import move

with open("in.txt") as f, NamedTemporaryFile("w",dir=".",delete=False) as out:
    grps = groupby(f,key=lambda x: x.startswith("$"))
    for k, v in grps:
        if k:
            val = next(v)
            out.write(val)
            if val.startswith("$ yum"):
                out.writelines(next(grps,[[], [""]])[1])
                out.write("I am a new line\n")
        else:
            out.writelines(v)
move(out.name,"in.txt")

The move(out.name,"in.txt") will change the original file content so the output will be:

$ yum -- to install package
admin1,group,n,0123456,/usr/bin 
user2,group,n,0123456,/usr/bin
group,n,0123456,/usr/bin
I am a new line
$cat -- to read contents of a file
admin1,group,n,0123456,/usr/bin
user2,group,n,0123456,/usr/bin
group,n,0123456,/usr/bin

Os use an inner loop every time you find a line starting with $ yum and breaking and writing the new line in the inner loop whenever you find the next $:

from tempfile import NamedTemporaryFile
from shutil import move

with open("in.txt") as f, NamedTemporaryFile("w",dir=".", delete=False) as out:
    for line in f:
        if line.startswith("$ yum"):
            out.write(line)
            for _line in f:
                if _line.startswith("$"):
                    out.write("I am a new line\n")
                    out.write(_line)
                    break
                out.write(_line)
        else:
            out.write(line)

move(out.name,"in.txt")

Answer 2


Using fileinput.input() you can easily and safely overwrite the input file without explicitly using a secondary file and then overwriting the original file:

import fileinput

extra_line = 'new line here...'
seen_yum = False
f = fileinput.input('test.txt', inplace=True)
for line in f:
    if line.startswith('$ yum'):
        seen_yum = True
    elif line.startswith('$') and seen_yum:
        print extra_line
    print line,
f.close()

For the input:

some other lines
of no interest to us
$ yum -- to install package
admin1,group,n,0123456,/usr/bin
user2,group,n,0123456,/usr/bin
group,n,0123456,/usr/bin
$cat -- to read contents of a file
admin1,group,n,0123456,/usr/bin
user2,group,n,0123456,/usr/bin
group,n,0123456,/usr/bin

the output would be:

some other lines
of no interest to us
$ yum -- to install package
admin1,group,n,0123456,/usr/bin 
user2,group,n,0123456,/usr/bin
group,n,0123456,/usr/bin
new line here...
$cat -- to read contents of a file
admin1,group,n,0123456,/usr/bin
user2,group,n,0123456,/usr/bin
group,n,0123456,/usr/bin

It's not clear from your question whether the extra line should be inserted before every subsequent line that starts with $ - as the code above does. If you only want one extra line inserted for every $ yum seen you can reset the seen_yum flag.

import fileinput

extra_line = 'new line here...'
seen_yum = False
f = fileinput.input('test.txt', inplace=True)
for line in f:
    if line.startswith('$ yum'):
        seen_yum = True
    elif line.startswith('$') and seen_yum:
        seen_yum = False
        print extra_line
    print line,
f.close()

So if the file contains multiple lines that start with $ yum, and there is a following line that begins with $, a new line will be inserted.