Editing specific line in text file in Python

Posted on

Question :

Editing specific line in text file in Python

Let’s say I have a text file containing:

Dan
Warrior
500
1
0

Is there a way I can edit a specific line in that text file? Right now I have this:

#!/usr/bin/env python
import io

myfile = open('stats.txt', 'r')
dan = myfile.readline()
print dan
print "Your name: " + dan.split('n')[0]

try:
    myfile = open('stats.txt', 'a')
    myfile.writelines('Mage')[1]
except IOError:
        myfile.close()
finally:
        myfile.close()

Yes, I know that myfile.writelines('Mage')[1] is incorrect. But you get my point, right? I’m trying to edit line 2 by replacing Warrior with Mage. But can I even do that?

Asked By: test

||

Answer #1:

You want to do something like this:

# with is like your try .. finally block in this case
with open('stats.txt', 'r') as file:
    # read a list of lines into data
    data = file.readlines()

print data
print "Your name: " + data[0]

# now change the 2nd line, note that you have to add a newline
data[1] = 'Magen'

# and write everything back
with open('stats.txt', 'w') as file:
    file.writelines( data )

The reason for this is that you can’t do something like “change line 2” directly in a file. You can only overwrite (not delete) parts of a file – that means that the new content just covers the old content. So, if you wrote ‘Mage’ over line 2, the resulting line would be ‘Mageior’.

Answered By: Jochen Ritzel

Answer #2:

you can use fileinput to do in place editing

import fileinput
for  line in fileinput.FileInput("myfile", inplace=1):
    if line .....:
         print line
Answered By: ghostdog74

Answer #3:

def replace_line(file_name, line_num, text):
    lines = open(file_name, 'r').readlines()
    lines[line_num] = text
    out = open(file_name, 'w')
    out.writelines(lines)
    out.close()

And then:

replace_line('stats.txt', 0, 'Mage')
Answered By: Peter C

Answer #4:

You can do it in two ways, choose what suits your requirement:

Method I.) Replacing using line number. You can use built-in function enumerate() in this case:

First, in read mode get all data in a variable

with open("your_file.txt",'r') as f:
    get_all=f.readlines()

Second, write to the file (where enumerate comes to action)

with open("your_file.txt",'w') as f:
    for i,line in enumerate(get_all,1):         ## STARTS THE NUMBERING FROM 1 (by default it begins with 0)    
        if i == 2:                              ## OVERWRITES line:2
            f.writelines("Magen")
        else:
            f.writelines(line)

Method II.) Using the keyword you want to replace:

Open file in read mode and copy the contents to a list

with open("some_file.txt","r") as f:
    newline=[]
    for word in f.readlines():        
        newline.append(word.replace("Warrior","Mage"))  ## Replace the keyword while you copy.  

“Warrior” has been replaced by “Mage”, so write the updated data to the file:

with open("some_file.txt","w") as f:
    for line in newline:
        f.writelines(line)

This is what the output will be in both cases:

Dan                   Dan           
Warrior   ------>     Mage       
500                   500           
1                     1   
0                     0           
Answered By: Aseem Yadav

Answer #5:

If your text contains only one individual:

import re

# creation
with open('pers.txt','wb') as g:
    g.write('Dan n Warrior n 500 rn 1 r 0 ')

with open('pers.txt','rb') as h:
    print 'exact content of pers.txt before treatment:n',repr(h.read())
with open('pers.txt','rU') as h:
    print 'nrU-display of pers.txt before treatment:n',h.read()


# treatment
def roplo(file_name,what):
    patR = re.compile('^([^rn]+[rn]+)[^rn]+')
    with open(file_name,'rb+') as f:
        ch = f.read()
        f.seek(0)
        f.write(patR.sub('\1'+what,ch))
roplo('pers.txt','Mage')


# after treatment
with open('pers.txt','rb') as h:
    print 'nexact content of pers.txt after treatment:n',repr(h.read())
with open('pers.txt','rU') as h:
    print 'nrU-display of pers.txt after treatment:n',h.read()

If your text contains several individuals:

import re

# creation
with open('pers.txt','wb') as g:
    g.write('Dan n Warrior n 500 rn 1 r 0 n Jim  n  dragonflyr300r2n10rnSomoncosmonautn490rn3r65')

with open('pers.txt','rb') as h:
    print 'exact content of pers.txt before treatment:n',repr(h.read())
with open('pers.txt','rU') as h:
    print 'nrU-display of pers.txt before treatment:n',h.read()


# treatment
def ripli(file_name,who,what):
    with open(file_name,'rb+') as f:
        ch = f.read()
        x,y = re.search('^s*'+who+'s*[rn]+([^rn]+)',ch,re.MULTILINE).span(1)
        f.seek(x)
        f.write(what+ch[y:])
ripli('pers.txt','Jim','Wizard')


# after treatment
with open('pers.txt','rb') as h:
    print 'exact content of pers.txt after treatment:n',repr(h.read())
with open('pers.txt','rU') as h:
    print 'nrU-display of pers.txt after treatment:n',h.read()

If the “job“ of an individual was of a constant length in the texte, you could change only the portion of texte corresponding to the “job“ the desired individual:
that’s the same idea as senderle’s one.

But according to me, better would be to put the characteristics of individuals in a dictionnary recorded in file with cPickle:

from cPickle import dump, load

with open('cards','wb') as f:
    dump({'Dan':['Warrior',500,1,0],'Jim':['dragonfly',300,2,10],'Somo':['cosmonaut',490,3,65]},f)

with open('cards','rb') as g:
    id_cards = load(g)
print 'id_cards before change==',id_cards

id_cards['Jim'][0] = 'Wizard'

with open('cards','w') as h:
    dump(id_cards,h)

with open('cards') as e:
    id_cards = load(e)
print 'nid_cards after change==',id_cards
Answered By: eyquem

Answer #6:

I have been practising working on files this evening and realised that I can build on Jochen’s answer to provide greater functionality for repeated/multiple use. Unfortunately my answer does not address issue of dealing with large files but does make life easier in smaller files.

with open('filetochange.txt', 'r+') as foo:
    data = foo.readlines()                  #reads file as list
    pos = int(input("Which position in list to edit? "))-1  #list position to edit
    data.insert(pos, "more foo"+"n")           #inserts before item to edit
    x = data[pos+1]
    data.remove(x)                      #removes item to edit
    foo.seek(0)                     #seeks beginning of file
    for i in data:
        i.strip()                   #strips "n" from list items
        foo.write(str(i))
Answered By: theYnot

Answer #7:

This is the easiest way to do this.

fin = open("a.txt")
f = open("file.txt", "wt")
for line in fin:
    f.write( line.replace('foo', 'bar') )
fin.close()
f.close()

I hope it will work for you.

Answered By: Rohit Nishad

Answer #8:

#read file lines and edit specific item

file=open("pythonmydemo.txt",'r')
a=file.readlines()
print(a[0][6:11])

a[0]=a[0][0:5]+' Ericssonn'
print(a[0])

file=open("pythonmydemo.txt",'w')
file.writelines(a)
file.close()
print(a)
Answered By: Ajay Jaiswal

Leave a Reply

Your email address will not be published. Required fields are marked *