Réponses:
Tout d'abord, ouvrez le fichier et récupérez toutes vos lignes du fichier. Ensuite, rouvrez le fichier en mode écriture et réécrivez vos lignes, à l'exception de la ligne que vous souhaitez supprimer:
with open("yourfile.txt", "r") as f:
lines = f.readlines()
with open("yourfile.txt", "w") as f:
for line in lines:
if line.strip("\n") != "nickname_to_delete":
f.write(line)
Vous avez besoin strip("\n")
du caractère de nouvelle ligne dans la comparaison car si votre fichier ne se termine pas par un caractère de nouvelle ligne, le tout dernier line
ne le sera pas non plus.
Solution à ce problème avec une seule ouverture:
with open("target.txt", "r+") as f:
d = f.readlines()
f.seek(0)
for i in d:
if i != "line you want to remove...":
f.write(i)
f.truncate()
Cette solution ouvre le fichier en mode r / w ("r +") et utilise seek pour réinitialiser le pointeur f puis tronquer pour tout supprimer après la dernière écriture.
for
boucle, vous vous retrouverez avec un fichier partiellement écrasé, avec des lignes en double ou une ligne à moitié coupée. Vous voudrez peut-être f.truncate()
juste après à la f.seek(0)
place. De cette façon, si vous obtenez une erreur, vous vous retrouverez avec un fichier incomplet. Mais la vraie solution (si vous avez l'espace disque) est de sortir dans un fichier temporaire puis de l'utiliser os.replace()
ou pathlib.Path(temp_filename).replace(original_filename)
de l'échanger avec l'original une fois que tout a réussi.
i.strip('\n') != "line you want to remove..."
comme mentionné dans la réponse acceptée, cela résoudrait parfaitement mon problème. Parce que je i
n'ai rien fait pour moi
La meilleure et la plus rapide option, plutôt que de tout stocker dans une liste et de rouvrir le fichier pour l'écrire, est à mon avis de réécrire le fichier ailleurs.
with open("yourfile.txt", "r") as input:
with open("newfile.txt", "w") as output:
for line in input:
if line.strip("\n") != "nickname_to_delete":
output.write(line)
C'est tout! Dans une boucle et une seule, vous pouvez faire la même chose. Ce sera beaucoup plus rapide.
(output.write(line) for line in input if line!="nickname_to_delete"+"\n")
subprocess.call(['mv', 'newfile.txt', 'yourfile.txt'])
os.replace
(nouveau dans python v 3.3) est plus multiplateforme qu'un appel système mv
.
C'est une "fourchette" de la réponse de @Lother (qui, je crois, devrait être considérée comme la bonne réponse).
Pour un fichier comme celui-ci:
$ cat file.txt
1: october rust
2: november rain
3: december snow
Cette fourchette de la solution de Lother fonctionne bien:
#!/usr/bin/python3.4
with open("file.txt","r+") as f:
new_f = f.readlines()
f.seek(0)
for line in new_f:
if "snow" not in line:
f.write(line)
f.truncate()
Améliorations:
with open
, qui rejette l'utilisation de f.close()
if/else
pour évaluer si la chaîne n'est pas présente dans la ligne couranteLe problème avec la lecture des lignes au premier passage et les modifications (suppression de lignes spécifiques) au second passage est que si la taille de vos fichiers est énorme, vous manquerez de RAM. Au lieu de cela, une meilleure approche consiste à lire les lignes, une par une, et à les écrire dans un fichier séparé, en éliminant celles dont vous n'avez pas besoin. J'ai utilisé cette approche avec des fichiers de 12 à 50 Go et l'utilisation de la RAM reste presque constante. Seuls les cycles CPU indiquent le traitement en cours.
J'ai aimé l'approche d'entrée de fichier comme expliqué dans cette réponse: Suppression d'une ligne d'un fichier texte (python)
Disons par exemple que j'ai un fichier contenant des lignes vides et que je souhaite supprimer les lignes vides, voici comment je l'ai résolu:
import fileinput
import sys
for line_number, line in enumerate(fileinput.input('file1.txt', inplace=1)):
if len(line) > 1:
sys.stdout.write(line)
Remarque: les lignes vides dans mon cas avaient la longueur 1
Si vous utilisez Linux, vous pouvez essayer l'approche suivante.
Supposons que vous ayez un fichier texte nommé animal.txt
:
$ cat animal.txt
dog
pig
cat
monkey
elephant
Supprimez la première ligne:
>>> import subprocess
>>> subprocess.call(['sed','-i','/.*dog.*/d','animal.txt'])
puis
$ cat animal.txt
pig
cat
monkey
elephant
Je pense que si vous lisez le fichier dans une liste, vous pouvez parcourir la liste pour rechercher le surnom dont vous souhaitez vous débarrasser. Vous pouvez le faire beaucoup plus efficacement sans créer de fichiers supplémentaires, mais vous devrez réécrire le résultat dans le fichier source.
Voici comment je pourrais faire ceci:
import, os, csv # and other imports you need
nicknames_to_delete = ['Nick', 'Stephen', 'Mark']
Je suppose que nicknames.csv
contient des données telles que:
Nick
Maria
James
Chris
Mario
Stephen
Isabella
Ahmed
Julia
Mark
...
Ensuite, chargez le fichier dans la liste:
nicknames = None
with open("nicknames.csv") as sourceFile:
nicknames = sourceFile.read().splitlines()
Ensuite, parcourez la liste pour faire correspondre vos entrées à supprimer:
for nick in nicknames_to_delete:
try:
if nick in nicknames:
nicknames.pop(nicknames.index(nick))
else:
print(nick + " is not found in the file")
except ValueError:
pass
Enfin, écrivez le résultat dans le fichier:
with open("nicknames.csv", "a") as nicknamesFile:
nicknamesFile.seek(0)
nicknamesFile.truncate()
nicknamesWriter = csv.writer(nicknamesFile)
for name in nicknames:
nicknamesWriter.writeRow([str(name)])
nicknamesFile.close()
En général, vous ne pouvez pas; vous devez réécrire le fichier entier (au moins du point de modification à la fin).
Dans certains cas spécifiques, vous pouvez faire mieux que cela -
si tous vos éléments de données sont de la même longueur et dans aucun ordre spécifique, et que vous connaissez le décalage de celui dont vous souhaitez vous débarrasser, vous pouvez copier le dernier élément sur celui à supprimer et tronquer le fichier avant le dernier élément ;
ou vous pouvez simplement écraser le bloc de données avec une valeur `` ce sont des données incorrectes, les ignorer '' ou conserver un indicateur `` cet élément a été supprimé '' dans vos éléments de données enregistrés de sorte que vous puissiez le marquer comme supprimé sans autrement modifier le fichier.
C'est probablement exagéré pour les documents courts (quelque chose de moins de 100 Ko?).
Vous avez probablement déjà une bonne réponse, mais voici la mienne. Au lieu d'utiliser une liste pour collecter des données non filtrées (quelle readlines()
méthode fait), j'utilise deux fichiers. Le premier est destiné à contenir les données principales et le second à filtrer les données lorsque vous supprimez une chaîne spécifique. Voici un code:
main_file = open('data_base.txt').read() # your main dataBase file
filter_file = open('filter_base.txt', 'w')
filter_file.write(main_file)
filter_file.close()
main_file = open('data_base.txt', 'w')
for line in open('filter_base'):
if 'your data to delete' not in line: # remove a specific string
main_file.write(line) # put all strings back to your db except deleted
else: pass
main_file.close()
J'espère que vous trouverez cela utile! :)
Enregistrez les lignes de fichier dans une liste, puis supprimez de la liste la ligne que vous souhaitez supprimer et écrivez les lignes restantes dans un nouveau fichier
with open("file_name.txt", "r") as f:
lines = f.readlines()
lines.remove("Line you want to delete\n")
with open("new_file.txt", "w") as new_f:
for line in lines:
new_f.write(line)
voici une autre méthode pour supprimer une / des ligne (s) d'un fichier:
src_file = zzzz.txt
f = open(src_file, "r")
contents = f.readlines()
f.close()
contents.pop(idx) # remove the line item from list, by line number, starts from 0
f = open(src_file, "w")
contents = "".join(contents)
f.write(contents)
f.close()
Vous pouvez utiliser la
re
bibliothèque
En supposant que vous puissiez charger votre fichier txt complet. Vous définissez ensuite une liste de surnoms indésirables, puis vous les remplacez par une chaîne vide "".
# Delete unwanted characters
import re
# Read, then decode for py2 compat.
path_to_file = 'data/nicknames.txt'
text = open(path_to_file, 'rb').read().decode(encoding='utf-8')
# Define unwanted nicknames and substitute them
unwanted_nickname_list = ['SourDough']
text = re.sub("|".join(unwanted_nickname_list), "", text)
Pour supprimer une ligne spécifique d'un fichier par son numéro de ligne :
Remplacez les variables filename et line_to_delete par le nom de votre fichier et le numéro de ligne que vous souhaitez supprimer.
filename = 'foo.txt'
line_to_delete = 3
initial_line = 1
file_lines = {}
with open(filename) as f:
content = f.readlines()
for line in content:
file_lines[initial_line] = line.strip()
initial_line += 1
f = open(filename, "w")
for line_number, line_content in file_lines.items():
if line_number != line_to_delete:
f.write('{}\n'.format(line_content))
f.close()
print('Deleted line: {}'.format(line_to_delete))
Exemple de sortie :
Deleted line: 3
for nb, line in enumerate(f.readlines())
Prenez le contenu du fichier, divisez-le par nouvelle ligne en un tuple. Ensuite, accédez au numéro de ligne de votre tuple, joignez votre tuple de résultat et écrasez-le dans le fichier.
tuple(f.read().split('\n'))
?? (2) "accéder au numéro de ligne de votre tuple" et "joindre votre tuple résultat" semblent plutôt mystérieux; le code Python réel pourrait être plus compréhensible.
fileinput
comme décrit par @ jf-sebastian ici . Il semble vous permettre de travailler ligne par ligne, via un fichier temporaire, le tout avec unefor
syntaxe simple .