Comment rechercher et remplacer du texte dans un fichier à l'aide de Python 3?
Voici mon code:
import os
import sys
import fileinput
print ("Text to search for:")
textToSearch = input( "> " )
print ("Text to replace it with:")
textToReplace = input( "> " )
print ("File to perform Search-Replace on:")
fileToSearch = input( "> " )
#fileToSearch = 'D:\dummy1.txt'
tempFile = open( fileToSearch, 'r+' )
for line in fileinput.input( fileToSearch ):
if textToSearch in line :
print('Match Found')
else:
print('Match Not Found!!')
tempFile.write( line.replace( textToSearch, textToReplace ) )
tempFile.close()
input( '\n\n Press Enter to exit...' )
Fichier d'entrée:
hi this is abcd hi this is abcd
This is dummy text file.
This is how search and replace works abcd
Lorsque je recherche et remplace «ram» par «abcd» dans le fichier d'entrée ci-dessus, cela fonctionne comme un charme. Mais quand je le fais vice-versa, c'est-à-dire en remplaçant «abcd» par «ram», certains caractères indésirables sont laissés à la fin.
Remplacement de 'abcd' par 'ram'
hi this is ram hi this is ram
This is dummy text file.
This is how search and replace works rambcd
Réponses:
fileinput
prend déjà en charge l'édition sur place. Il redirigestdout
vers le fichier dans ce cas:la source
end=''
argument censé faire?line
a déjà une nouvelle ligne.end
est une nouvelle ligne par défaut,end=''
fait que laprint()
fonction n'imprime pas de nouvelle ligne supplémentairefileinput
n'est pas un outil pour tous les emplois ( rien est) , mais il y a beaucoup de cas où il est l'outil approprié , par exemple, mettre en place unsed
filtre -comme en Python. N'utilisez pas de tournevis pour marteler les ongles.fileinput
fait (en gros, utiliseztry..finally
ou un gestionnaire de contexte pour vous assurer de remettre stdout à sa valeur d'origine par la suite). Le code source defileinput
est assez affreux, et il fait des choses vraiment dangereuses sous le capot. Si elle avait été écrite aujourd'hui, je doute fort qu'elle aurait pu figurer dans le stdlib.Comme l'a souligné michaelb958, vous ne pouvez pas remplacer en place par des données d'une longueur différente car cela mettra le reste des sections à leur place. Je ne suis pas d'accord avec les autres affiches vous suggérant de lire un fichier et d'écrire dans un autre. Au lieu de cela, je lis le fichier en mémoire, corrige les données, puis l'écris dans le même fichier dans une étape distincte.
À moins que vous n'ayez un fichier volumineux à travailler qui soit trop volumineux pour être chargé en mémoire en une seule fois, ou que vous ne soyez préoccupé par la perte potentielle de données si le processus est interrompu pendant la deuxième étape au cours de laquelle vous écrivez des données dans le fichier.
la source
with file = open(..):
n'est pas valide Python (=
) bien que l'intention soit claire..replace()
ne modifie pas la chaîne (elle est immuable), vous devez donc utiliser la valeur renvoyée. Quoi qu'il en soit, le code qui prend en charge les gros fichiers peut être encore plus simple, sauf si vous devez rechercher et remplacer du texte qui s'étend sur plusieurs lignes.with
instruction ferme automatiquement le fichier à la fin du bloc d'instruction.Comme Jack Aidley l'avait signalé et JF Sebastian l'a souligné, ce code ne fonctionnera pas:
Mais ce code fonctionnera (je l'ai testé):
En utilisant cette méthode, filein et fileout peuvent être le même fichier, car Python 3.3 écrasera le fichier lors de son ouverture en écriture.
la source
with
déclaration? 2. Comme indiqué dans ma réponse,fileinput
peut fonctionner sur place - il peut remplacer les données dans le même fichier (il utilise un fichier temporaire en interne). La différence est qu'ilfileinput
ne nécessite pas de charger tout le fichier en mémoire.with
blocs plus nets ).Vous pouvez faire le remplacement comme ceci
la source
Vous pouvez également utiliser
pathlib
.la source
Avec un simple avec bloc, vous pouvez rechercher et remplacer votre texte:
la source
seek
début du fichier avant de l'écrire.truncate
ne fait pas cela et vous aurez donc des ordures dans le fichier.Votre problème provient de la lecture et de l'écriture dans le même fichier. Plutôt que d'ouvrir
fileToSearch
pour l'écriture, ouvrez un fichier temporaire réel, puis une fois que vous avez terminé et fermétempFile
, utilisezos.rename
pour déplacer le nouveau fichierfileToSearch
.la source
(pip installe python-util)
Le deuxième paramètre (la chose à remplacer, par exemple "abcd" peut également être une expression régulière)
remplacera toutes les occurrences
la source
Ma variante, un mot à la fois sur l'ensemble du dossier.
Je l'ai lu en mémoire.
la source
Je l'ai fait:
la source
fileinput
ne fonctionne pasinplace=True
avecutf-8
.J'ai légèrement modifié le post de Jayram Singh afin de remplacer chaque instance d'un '!' caractère à un nombre que je voulais incrémenter à chaque instance. Je pensais que cela pourrait être utile à quelqu'un qui voulait modifier un personnage qui se produisait plus d'une fois par ligne et voulait itérer. J'espère que cela aide quelqu'un. PS- Je suis très nouveau dans le codage, donc je m'excuse si mon message est inapproprié de quelque façon que ce soit, mais cela a fonctionné pour moi.
la source
la source
Ainsi:
la source
la source