Bonjour,
Je voudrais dans un fichier, trouver un élément d'une ligne et supprimer entièrement cette ligne.
Quelqu'un a une solution?
Bonne journée
Version imprimable
Bonjour,
Je voudrais dans un fichier, trouver un élément d'une ligne et supprimer entièrement cette ligne.
Quelqu'un a une solution?
Bonne journée
Salut
Le plus simple, c'est de prendre les lignes de ton fichier une à une, et de les réécrire dans un nouveau fichier. Quitte à renommer après si besoin.
Avec Python >= 2.6
Code:
1
2
3
4
5 with open("fichier_en_entree") as fin: with open("fichier_en_sortie", "w") as fout: for line in fin: if il_faut_lecrire(): fout.write(line)
Est-ce qu'il n'est pas possible de l'ouvrir en "a" (append)? Car je préferais ne pas réécrire dans un nouveau fichier car mon script va devenir vite ingérable :?
Egalement après avoir fait un "find" sur l'élément en question, est-il possible de supprimer la ligne entière sur lequel se trouve l'élément?
Bonjour,
Tu serais pas dans la même classe que storm85, des fois ?
http://www.developpez.net/forums/d93...e/#post5246010
:lol:
Tu dervais trouver des réponses et des indications à partir du post suivant:
http://www.developpez.net/forums/d93...e/#post5246139
Et pour voir rapidement un exemple concret , descends jusqu’au post # 10 dans cette file.
Si tu continues à avoir des difficultés, on t’aidera de façon plus précise.
----------------------------------------
Mais pour répondre à tes questions:
« trouver un élément d'une ligne »
cela suppose qu’on lise le fichier
« supprimer entièrement cette ligne »
cela suppose qu’on écrive en écrasant dans le fichier, ou qu’on écrive un autre fichier en ’oubliant’ la ligne concernée
Dans le premier cas, il faut ouvrir en ’r’
Dans le second, il faut ouvrir en mode ’w’.
Ou bien, pour faire les deux sans avoir à fermer et rouvrir entre le mode ’r’ et le mode ’w’, il faut ouvrir en ’r+’.
Si tu ouvres en ’a+’, toute instruction d’écriture n’écrira qu’à la fin du fichier: le mode ’a’ ou ’a+’ est un mode de protection des données, chaque fois qu’une instruction write() est exécutée dans un tel mode, elle est précédée d’un déplacement du curseur de fichier à la fin de celui-ci.
---------------------------------
Par ailleurs, pourquoi réécrire dans un nouveau fichier serait il plus ingérable que de modifier en place un fichier ?
Euh non du tout storm85 n'est pas dans ma classe mais c'est vrai que l'on a un peu le même problème. Le hasard fait bien les choses :lol:
Je disais que ça pouvait devenir ingérable car il faudrait supprimer les anciens fichiers qui ne servent plus, non?
Merci pour les posts
Il y a tout ce qu’il faut pour s’occuper de fichiers et de dossiers dans les modules os et os.path
Par exemple remove() qui permet de détruire un fichier.
J'ai regardé tes posts sur le traitement de fichier, qui sont d'ailleurs très bien fait et précis, mais je comprends toujours pas, j'ai essayé d'adapter ce que tu as expliqué à mon cas, sans résultat.
Citation:
Mon fichier:
host client1.domain.fr { hardware ethernet 00:0A:95:F3:24:A0; fixed-address 194.254.111.227; }
host client3.domain.fr { hardware ethernet 00:A0:F1:29:68:55; fixed-address 194.254.111.193; }
Il me renvoit comme réponse:Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #La ligne à supprimer est celle où se trouve la chaine de caractère "client3" chaine= r"client3" contenu="" with open ('/home/kevin/194.254.111.192.net', "r+b") as f: ch = f.read() x = ch.find(chaine) x = ch[0:x].rfind('\n') + 1 f.seek(x) for ligne in f[x:]: if not(chaine in ligne): contenu+=ligne f.seek(x) f.write(contenu) f.close()
Citation:
Traceback (most recent call last):
File "<pyshell#126>", line 6, in <module>
for ligne in f[x:]:
TypeError: 'file' object is unsubscriptable
Pour la réponse que tu as fourni à storm85, j'ai bien cerné son problème mais pas compris ton script :cry: dsl.
f est un objet-fichier, ce n’est pas une séquence dont on puisse désigner un élément par f[45] ou une section par f[47:123]
Avec ma tendance à écrire le plus concis possible et utiliser le moins de noms de références (ce qui est appelé noms de variables dans d’autres langages) , c’est vrai que ça rend la compréhension moins coulante.
Le code dont tu t’es inspiré ne convient pas pour ce que tu veux faire. Il recopie toutes les lignes d’un fichier sauf celles qui contiennent une certaine chaîne. Cela oblige à passer les lignes en revue l’une après l’autre, en tant que lignes, c’est à dire qu’on ne peut pas traiter le fichier sous forme brute d’un fichier de caractères sans se préoccuper des fins de lignes.
( En réalité ce code ne recopie pas la totalité du fichier dans un autre fichier, il recopie dans le même fichier des lignes lues plus en avant de la position du curseur de positionnement dans l’objet-fichier. )
Tandis que toi, tu souhaites éliminer seulement une ligne, d’après ce que j’ai compris.
Le code suivant devrait donc t’aller:
splitlines(1) conserve les fins de ligneCode:
1
2
3
4
5
6
7
8 chaine= r"client3" with open ('/home/kevin/194.254.111.192.net', "r+b") as f: ch = f.read() x = ch.find(chaine) ante = ch[0:x].rfind('\n') + 1 post = ch[x:].find('\n') + 1 f.seek(ante) f.write(ch[post:])
splitlines() non.
La ligne f.seek(x) avant de faire f.write(contenu) est nécessaire pour positionner le curseur d’objet-fichier à l’endroit précis où l’on veut commencer à écrire la suite.
En effet, à la suite de la lecture f.read() du fichier f , ce curseur se trouve à la toute fin du fichier.
En utilisant le statement with , il n’y a pas besoin de f.close() , la fermeture du fichier dans de bonnes conditions est automatiquement faite, même en cas d’erreur survenue dans le déroulement à l’intérieur.
Attention, ce code suppose que les fins de ligne sont du type ’\n’ seul ou ’\r\n’.
Mais ça ne marchera pas si c’est un fichier sur plateforme Mac dont les fins de ligne sont ’\r’. Il faudra adapter.
À titre informatif, pour éliminer l’erreur dont tu fais part en gardant la boucle sur des lignes, il faut écrire:
ouCode:
1
2
3
4
5
6
7
8
9
10 chaine= r"client3" with open ('/home/kevin/194.254.111.192.net', "r+b") as f: ch = f.read() x = ch.find(chaine) ante = ch[0:x].rfind('\n') + 1 for ligne in ch[x:].splitlines(1): if not(chaine in ligne): contenu+=ligne f.seek(ante) f.write(contenu)
La deuxième écriture évite un objet ch[x:].splitlines(1) dont l’itération est plus lente que celle de f directement ( for ligne in f: ) car f est son propre itérateur.Code:
1
2
3
4
5
6
7
8
9
10
11 chaine= r"client3" with open ('/home/kevin/194.254.111.192.net', "r+b") as f: ch = f.read() x = ch.find(chaine) ante = ch[0:x].rfind('\n') + 1 f.seek(ante) for ligne in f: if not(chaine in ligne): contenu+=ligne f.seek(ante) f.write(contenu)
On pourrait faire aussi
mais on aurait deux défauts à la fois, celui avec ch[x:].splitlines(1) , et celui dû à la réitération d’écritures fréquentes:Code:
1
2
3
4
5
6
7
8
9 chaine= r"client3" with open ('/home/kevin/194.254.111.192.net', "r+b") as f: ch = f.read() x = ch.find(chaine) ante = ch[0:x].rfind('\n') + 1 f.seek(ante) for ligne in ch[x:].splitlines(1): if not(chaine in ligne): f.write(ligne)
il est plus rapide d’aggréger toutes les lignes dans un objet contenu avant de l’écrire d’un seul coup que de réitérer des petit crqachotis d’écritures pour chaque ligne (en fait ellles s’accumulent dans le buffer avant que celui ci soit déversé en écriture, mais ça diminue le nombre de coups d’écriture, ça ne le fait pas descendre à 1 si le fichier est grand).
Merci pour la solution, la correction des erreurs et surtout pour les explications qui sont bien utiles pour comprendre.
C'est excatement ce que je voulais.