Je veux parcourir le contenu d'un fichier texte et faire une recherche et remplacer sur certaines lignes et écrire le résultat dans le fichier. Je pourrais d'abord charger le fichier entier en mémoire puis le réécrire, mais ce n'est probablement pas la meilleure façon de le faire.
Quelle est la meilleure façon de procéder, dans le code suivant?
f = open(file)
for line in f:
if line.contains('foo'):
newline = line.replace('foo', 'bar')
# how to write this newline back to the file
file
c'est l'observation d'une classe prédéfinie du même nom.mkstemp()
renvoyait un double et(fh, abs_path) = fh, abs_path
je ne le savais pas quand j'ai posé la question.Le moyen le plus court serait probablement d'utiliser le module d'entrée de fichier . Par exemple, ce qui suit ajoute des numéros de ligne à un fichier, sur place:
Ce qui se passe ici est:
print
instructions sont réécrites dans le fichier d'originefileinput
a plus de cloches et de sifflets. Par exemple, il peut être utilisé pour fonctionner automatiquement sur tous les fichiers desys.args[1:]
, sans que vous ayez à les parcourir explicitement. À partir de Python 3.2, il fournit également un gestionnaire de contexte pratique à utiliser dans unewith
instruction.Bien qu'il
fileinput
soit idéal pour les scripts jetables, je me méfierais de l'utiliser dans du vrai code car il est vrai qu'il n'est pas très lisible ou familier. Dans le code réel (de production), il vaut la peine de dépenser quelques lignes de code supplémentaires pour rendre le processus explicite et ainsi rendre le code lisible.Il y a deux options:
la source
print(line, end='')
Voici un autre exemple qui a été testé et qui correspondra aux modèles de recherche et de remplacement:
Exemple d'utilisation:
la source
searchExp in line
neline.replace
sont des opérations d'expression régulière. Certes, l'exemple d'utilisation est faux.if searchExp in line: line = line.replace(searchExp, replaceExpr)
vous, vous pouvez simplement écrireline = line.replace(searchExp, replaceExpr)
. Aucune exception n'est générée, la ligne reste inchangée.sys.stdout.write(line)
. Merci encore!Cela devrait fonctionner: (édition sur place)
la source
files
doit s'agir d'une chaîne contenant le nom du fichier et non d'un objet fichier .Basé sur la réponse de Thomas Watnedal. Cependant, cela ne répond pas exactement à la partie ligne à ligne de la question d'origine. La fonction peut toujours être remplacée ligne par ligne
Cette implémentation remplace le contenu du fichier sans utiliser de fichiers temporaires, par conséquent les autorisations de fichier restent inchangées.
Aussi re.sub au lieu de replace, permet le remplacement regex au lieu du remplacement en texte brut uniquement.
La lecture du fichier sous la forme d'une chaîne unique au lieu d'une ligne par ligne permet une correspondance et un remplacement sur plusieurs lignes.
la source
rb
etwb
lors de l'ouverture des fichiers car cela préservera les fins de ligne d'origineComme le suggère lassevk, écrivez le nouveau fichier au fur et à mesure, voici un exemple de code:
la source
Si vous voulez une fonction générique qui remplace n'importe quel texte par un autre texte, c'est probablement la meilleure façon de procéder, en particulier si vous êtes un fan des expressions régulières:
la source
Une manière plus pythonique serait d'utiliser des gestionnaires de contexte comme le code ci-dessous:
Vous pouvez trouver l'extrait complet ici .
la source
Créez un nouveau fichier, copiez les lignes de l'ancien vers le nouveau et effectuez le remplacement avant d'écrire les lignes dans le nouveau fichier.
la source
En développant la réponse de @ Kiran, qui, je suis d'accord, est plus succincte et Pythonic, cela ajoute des codecs pour prendre en charge la lecture et l'écriture de l'UTF-8:
la source
En utilisant la réponse de hamishmcn comme modèle, j'ai pu rechercher une ligne dans un fichier qui correspond à mon expression régulière et la remplacer par une chaîne vide.
la source
fileinput
est assez simple comme mentionné dans les réponses précédentes:Explication:
fileinput
peut accepter plusieurs fichiers, mais je préfère fermer chaque fichier dès qu'il est en cours de traitement. Donc placé seulfile_path
dans lawith
déclaration.print
L'instruction n'imprime rien quandinplace=True
, car elleSTDOUT
est transmise au fichier d'origine.end=''
dans l'print
instruction est d'éliminer les nouvelles lignes vierges intermédiaires.Peut être utilisé comme suit:
la source
si vous supprimez le retrait comme ci-dessous, il recherchera et remplacera sur plusieurs lignes. Voir ci-dessous par exemple.
la source