Disons que j'ai un fichier texte contenant:
Dan
Warrior
500
1
0
Est-il possible de modifier une ligne spécifique dans ce fichier texte? En ce moment j'ai ceci:
#!/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()
Oui, je sais que myfile.writelines('Mage')[1]
est incorrect. Mais vous obtenez mon point, non? J'essaie de modifier la ligne 2 en remplaçant Warrior par Mage. Mais puis-je même faire ça?
Vous voulez faire quelque chose comme ça:
# 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] = 'Mage\n'
# and write everything back
with open('stats.txt', 'w') as file:
file.writelines( data )
La raison en est que vous ne pouvez pas faire quelque chose comme "modifier la ligne 2" directement dans un fichier. Vous pouvez uniquement écraser (et non supprimer) des parties d'un fichier, ce qui signifie que le nouveau contenu ne couvre que l'ancien contenu. Donc, si vous écrivez "Mage" sur la ligne 2, la ligne résultante sera "Mageior".
vous pouvez utiliser fileinput pour faire de la modification sur place
import fileinput
for line in fileinput.FileInput("myfile", inplace=1):
if line .....:
print line
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()
Et alors:
replace_line('stats.txt', 0, 'Mage')
Si votre texte ne contient qu'un seul individu:
import re
# creation
with open('pers.txt','wb') as g:
g.write('Dan \n Warrior \n 500 \r\n 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('^([^\r\n]+[\r\n]+)[^\r\n]+')
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()
Si votre texte contient plusieurs individus:
import re
# creation
with open('pers.txt','wb') as g:
g.write('Dan \n Warrior \n 500 \r\n 1 \r 0 \n Jim \n dragonfly\r300\r2\n10\r\nSomo\ncosmonaut\n490\r\n3\r65')
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*[\r\n]+([^\r\n]+)',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()
Si le "travail" d’un individu a une longueur constante dans le texte, vous ne pouvez modifier que la partie du texte correspondant au "travail" de l’individu souhaité: c’est la même idée que celle de senderle.
Mais selon moi, il serait préférable de mettre les caractéristiques des individus dans un dictionnaire enregistré dans un fichier avec 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
Vous pouvez le faire de deux manières, choisissez ce qui convient à vos besoins:
Méthode I.) Remplacement par le numéro de ligne. Vous pouvez utiliser la fonction intégrée enumerate()
dans ce cas:
Tout d'abord, en mode lecture récupère toutes les données d'une variable
with open("your_file.txt",'r') as f:
get_all=f.readlines()
Deuxièmement, écrivez dans le fichier (où énumérer vient à l'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("Mage\n")
else:
f.writelines(line)
Méthode II.) En utilisant le mot-clé que vous voulez remplacer:
Ouvrir le fichier en mode en lecture et copier le contenu dans une liste
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" a été remplacé par "Mage", écrivez donc les données mises à jour dans le fichier:
with open("some_file.txt","w") as f:
for line in newline:
f.writelines(line)
Voici ce que sortie sera dans les deux cas:
Dan Dan
Warrior ------> Mage
500 500
1 1
0 0
Je me suis entraîné à travailler sur des fichiers ce soir et je me suis rendu compte que je pouvais me baser sur la réponse de Jochen pour fournir une plus grande fonctionnalité pour un usage répété/multiple. Malheureusement, ma réponse n'aborde pas le problème du traitement des fichiers volumineux, mais facilite la vie dans les fichiers plus petits.
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))