[ 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.