Quiero recorrer el contenido de un archivo de texto y hacer una búsqueda y reemplazar en algunas líneas y escribir el resultado en el archivo. Primero podría cargar todo el archivo en la memoria y luego volver a escribirlo, pero probablemente esa no sea la mejor manera de hacerlo.
¿Cuál es la mejor manera de hacer esto, dentro del siguiente código?
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
está sombreando una clase predefinida del mismo nombre.mkstemp()
está devolviendo una tupla de 2 y(fh, abs_path) = fh, abs_path
no lo sabía cuando hice la pregunta.La forma más corta probablemente sería usar el módulo de entrada de archivo . Por ejemplo, lo siguiente agrega números de línea a un archivo, en el lugar:
Lo que pasa aquí es:
print
declaración vuelve a escribirse en el archivo originalfileinput
Tiene más campanas y silbatos. Por ejemplo, se puede usar para operar automáticamente en todos los archivossys.args[1:]
, sin tener que repetirlos explícitamente. Comenzando con Python 3.2, también proporciona un administrador de contexto conveniente para usar en unawith
declaración.Si bien
fileinput
es excelente para los scripts desechables, desconfiaría de usarlo en código real porque es cierto que no es muy legible o familiar. En el código real (de producción) vale la pena gastar unas pocas líneas de código más para hacer que el proceso sea explícito y, por lo tanto, hacer que el código sea legible.Hay dos opciones:
fuente
print(line, end='')
Aquí hay otro ejemplo que se probó y que coincidirá con los patrones de búsqueda y reemplazo:
Ejemplo de uso:
fuente
searchExp in line
tampoco loline.replace
son las operaciones de expresión regular. Seguramente el uso del ejemplo es incorrecto.if searchExp in line: line = line.replace(searchExp, replaceExpr)
ti solo puedes escribirline = line.replace(searchExp, replaceExpr)
. No se genera ninguna excepción, la línea simplemente permanece sin cambios.sys.stdout.write(line)
. ¡Gracias de nuevo!Esto debería funcionar: (edición in situ)
fuente
files
debe ser una cadena que contenga el nombre del archivo, no un objeto de archivo .Basado en la respuesta de Thomas Watnedal. Sin embargo, esto no responde exactamente la parte de línea a línea de la pregunta original. La función aún puede reemplazarse de línea a línea
Esta implementación reemplaza el contenido del archivo sin usar archivos temporales, como consecuencia los permisos de archivo permanecen sin cambios.
También re.sub en lugar de reemplazar, permite el reemplazo de expresiones regulares en lugar del reemplazo de texto sin formato solamente.
Leer el archivo como una sola cadena en lugar de línea por línea permite la coincidencia y el reemplazo de varias líneas.
fuente
rb
ywb
atributos al abrir archivos, ya que esto preservará las terminaciones de línea originalesComo sugiere lassevk, escriba el nuevo archivo a medida que avanza, aquí hay un código de ejemplo:
fuente
Si desea una función genérica que reemplace cualquier texto con otro texto, esta es probablemente la mejor manera de hacerlo, especialmente si es fanático de las expresiones regulares:
fuente
Una forma más pitónica sería usar administradores de contexto como el código a continuación:
Puedes encontrar el fragmento completo aquí .
fuente
Cree un nuevo archivo, copie las líneas de la antigua a la nueva y reemplace antes de escribir las líneas en el nuevo archivo.
fuente
Ampliando la respuesta de @ Kiran, que estoy de acuerdo es más sucinta y pitónica, esto agrega códecs para apoyar la lectura y escritura de UTF-8:
fuente
Utilizando la respuesta de hamishmcn como plantilla, pude buscar una línea en un archivo que coincida con mi expresión regular y reemplazarla con una cadena vacía.
fuente
fileinput
es bastante sencillo como se menciona en las respuestas anteriores:Explicación:
fileinput
puede aceptar varios archivos, pero prefiero cerrar cada archivo tan pronto como se esté procesando. Así colocado solofile_path
en lawith
declaración.print
la declaración no imprime nada cuandoinplace=True
, porqueSTDOUT
se reenvía al archivo original.end=''
en laprint
declaración es eliminar nuevas líneas intermedias en blanco.Se puede usar de la siguiente manera:
fuente
si quita la sangría en el siguiente ejemplo, buscará y reemplazará en varias líneas. Ver abajo por ejemplo.
fuente