¿Es posible modificar líneas en un archivo en el lugar?

¿Es posible analizar un archivo línea por línea y editar una línea en el lugar mientras pasa por las líneas?

¿Es posible analizar un archivo línea por línea y editar una línea en el lugar mientras pasa por las líneas?

Se puede simular utilizando un archivo de copia de seguridad como lo hace el módulo de fileinput archivo de fileinput .

Aquí hay una secuencia de comandos de ejemplo que elimina las líneas que no satisfacen la some_condition de some_condition de los archivos dados en la línea de comandos o en la stdin :

 #!/usr/bin/env python # grep_some_condition.py import fileinput for line in fileinput.input(inplace=True, backup='.bak'): if some_condition(line): print line, # this goes to the current file 

Ejemplo:

 $ python grep_some_condition.py first_file.txt second_file.txt 

Al completarse, los archivos first_file.txt y second_file.txt contendrán solo líneas que satisfacen el predicado some_condition() .

El módulo de entrada de archivo tiene una API muy fea. Encuentro un módulo hermoso para esta tarea – in_place , ejemplo para Python 3:

 import in_place with in_place.InPlace('data.txt') as file: for line in file: line = line.replace('test', 'testZ') file.write(line) 

principal diferencia de fileinput:

  • En lugar de secuestrar sys.stdout, se devuelve un nuevo identificador de archivo para la escritura.
  • El identificador de archivo admite todos los métodos de E / S estándar, no solo readline ().

No. No puede escribir de forma segura en un archivo que también está leyendo, ya que cualquier cambio que realice en el archivo podría sobrescribir el contenido que aún no haya leído. Para hacerlo de forma segura, tendría que leer el archivo en un búfer, actualizar las líneas según sea necesario y, a continuación, volver a escribir el archivo.

Si está reemplazando byte por byte el contenido en el archivo (es decir, si el texto que está reemplazando tiene la misma longitud que la nueva cadena con la que lo está reemplazando), entonces puede salirse con la suya, pero es una avispa anidar, así que me ahorraría la molestia y solo leería el archivo completo, reemplazaría el contenido de la memoria (o mediante un archivo temporal) y lo escribiría de nuevo.

Si solo tiene la intención de realizar cambios localizados que no cambien la longitud de la parte del archivo que se modifica (por ejemplo, cambiando todos los caracteres a minúsculas), entonces puede sobrescribir dinámicamente los contenidos antiguos del archivo.

Para hacerlo, puede usar el acceso aleatorio a los archivos con el método seek() de un objeto de file .

Alternativamente, puede usar un objeto mmap para tratar todo el archivo como una cadena mutable. Tenga en cuenta que los objetos mmap pueden imponer un límite máximo de tamaño de archivo en el rango de 2 a 4 GB en una CPU de 32 bits, según su sistema operativo y su configuración.

Tienes que hacer una copia de seguridad por el tamaño de la línea en caracteres. Suponiendo que usó readline , entonces puede obtener la longitud de la línea y hacer una copia de seguridad utilizando:

 file.seek(offset[, whence]) 

Establezca SEEK_CUR en SEEK_CUR , establezca offset en -length .

Consulte Python Docs o mire la página del manual para seek .