¿Cómo busco y reemplazo texto en un archivo usando Python 3?
Aquí está mi código:
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...' )
Fichero de entrada:
hi this is abcd hi this is abcd
This is dummy text file.
This is how search and replace works abcd
Cuando busco y reemplazo 'ram' por 'abcd' en el archivo de entrada anterior, funciona como un encanto. Pero cuando lo hago al revés, es decir, reemplazando 'abcd' por 'ram', quedan algunos caracteres basura al final.
Reemplazando 'abcd' por 'ram'
hi this is ram hi this is ram
This is dummy text file.
This is how search and replace works rambcd
Respuestas:
fileinput
ya es compatible con la edición in situ. Redirigestdout
al archivo en este caso:fuente
end=''
supone que debe hacer el argumento?line
Ya tiene una nueva línea.end
es una nueva línea por defecto,end=''
hace que laprint()
función no imprima nueva línea adicionalfileinput
no es una herramienta para todos los trabajos ( nada lo es) pero hay muchos casos en los que es la herramienta adecuada, por ejemplo, para implementar unsed
filtro similar en Python. No use un destornillador para golpear las uñas.fileinput
lo que lo hace (básicamente, usetry..finally
o un administrador de contexto para asegurarse de volver a establecer stdout en su valor original después). El código fuentefileinput
es bastante horrible, y hace algunas cosas realmente inseguras bajo el capó. Si se hubiera escrito hoy, dudo mucho que hubiera llegado al stdlib.Como lo señaló michaelb958, no puede reemplazar en el lugar con datos de una longitud diferente porque esto hará que el resto de las secciones estén fuera de lugar. No estoy de acuerdo con los otros carteles que sugieren que lea de un archivo y escriba en otro. En cambio, leería el archivo en la memoria, arreglaría los datos y luego lo escribiría en el mismo archivo en un paso separado.
A menos que tenga un archivo masivo para trabajar que sea demasiado grande para cargar en la memoria de una sola vez, o le preocupe la posible pérdida de datos si el proceso se interrumpe durante el segundo paso en el que escribe datos en el archivo.
fuente
with file = open(..):
no es válido Python (=
) aunque la intención es clara..replace()
no modifica la cadena (es inmutable), por lo que debe usar el valor devuelto. De todos modos, el código que admite archivos grandes puede ser aún más simple a menos que necesite buscar y reemplazar texto que abarque varias líneas.with
declaración cierra automáticamente el archivo al final del bloque de la declaración.Como Jack Aidley había publicado y JF Sebastian señaló, este código no funcionará:
Pero este código funcionará (lo he probado):
Con este método, filein y fileout pueden ser el mismo archivo, porque Python 3.3 sobrescribirá el archivo al abrirlo para escribir.
fuente
with
-declaración? 2. Como se indicó en mi respuesta,fileinput
puede funcionar en el lugar, puede reemplazar los datos en el mismo archivo (utiliza un archivo temporal internamente). La diferencia es quefileinput
no requiere cargar todo el archivo en la memoria.with
bloques más limpios ).Puedes hacer el reemplazo así
fuente
También puedes usar
pathlib
.fuente
Con un solo bloque, puede buscar y reemplazar su texto:
fuente
seek
principio del archivo antes de escribirlo.truncate
no hace eso y tendrás basura en el archivo.Su problema proviene de leer y escribir en el mismo archivo. En lugar de abrir
fileToSearch
para escribir, abra un archivo temporal real y luego, una vez que haya terminado y haya cerradotempFile
, useos.rename
para mover el nuevo archivofileToSearch
.fuente
(pip install python-util)
El segundo parámetro (la cosa a ser reemplazada, por ejemplo, "abcd" también puede ser una expresión regular)
Reemplazará todas las ocurrencias
fuente
Mi variante, una palabra a la vez en todo el archivo.
Lo leí en la memoria.
fuente
He hecho esto:
fuente
fileinput
no trabajasinplace=True
conutf-8
.Modifiqué un poco la publicación de Jayram Singh para reemplazar cada instancia de un '!' carácter a un número que quería incrementar con cada instancia. Pensé que podría ser útil para alguien que quería modificar un carácter que ocurría más de una vez por línea y quería iterar. Espero que ayude a alguien. PD: soy muy nuevo en la codificación, así que me disculpo si mi publicación es inapropiada de alguna manera, pero esto funcionó para mí.
fuente
fuente
Al igual que:
fuente
fuente