Leer y sobrescribir un archivo en Python


Actualmente estoy usando esto:

f = open(filename, 'r+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.close()

Pero el problema es que el archivo antiguo es más grande que el nuevo. Así que termino con un nuevo archivo que tiene una parte del archivo antiguo al final de la misma.

Author: compie, 2010-03-11

4 answers

Si no desea cerrar y volver a abrir el archivo, para evitar condiciones de carrera, podría truncate it:

f = open(filename, 'r+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.truncate()
f.close()

La funcionalidad también puede ser más limpia y segura usando with open as según el comentario de mVChr, que cerrará el controlador, incluso si se produce un error.

with open(filename, 'r+') as f:
    text = f.read()
    text = re.sub('foobar', 'bar', text)
    f.seek(0)
    f.write(text)
    f.truncate()
 149
Author: nosklo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:47

Probablemente sería más fácil y ordenado cerrar el archivo después de text = re.sub('foobar', 'bar', text), volver a abrirlo para escribir (borrando así el contenido antiguo), y escribir su texto actualizado en él.

 15
Author: Il-Bhima,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-11 10:04:09

El fileinput el módulo tiene un modo inline para escribir cambios en el archivo que está procesando sin usar archivos temporales, etc. El módulo encapsula muy bien la operación común de bucle sobre las líneas en una lista de archivos, a través de un objeto que realiza un seguimiento transparente del nombre del archivo, número de línea, etc. si desea inspeccionarlos dentro del bucle.

import fileinput
for line in fileinput.FileInput("file",inplace=1):
    if "foobar" in line:
         line=line.replace("foobar","bar")
    print line
 14
Author: ghostdog74,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-11 05:54:44

Intenta escribirlo en un archivo nuevo..

f = open(filename, 'r+')
f2= open(filename2,'a+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.close()
f2.write(text)
fw.close()
 -2
Author: sk7979,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-29 11:59:40