2011-03-27 29 views
37

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

+1

Es posible bajo ciertas condiciones. Si la línea resultante de la edición de una línea tratada es más corta o de la misma longitud que la línea tratada, es fácil de hacer. Si no es el caso, se vuelve más difícil, aunque no imposible, si las líneas que se someten a la edición no son demasiado numerosas. ¿Le preguntas esto porque quieres tratar un gran archivo? – eyquem

+1

>>> f = abrir ('tmp', 'r +') >>> f.readline() '75 .14 \ n ' >>> f.readline() '100 \ n' >>> l = _ >>> f.seek (-l.len(), file.SEEK_CUR) >>> f.seek (-len (l), os .SEEK_CUR) >>> f.write ('999 \ n') >>> f.close() >>> – Bob

+0

Vea el ejemplo aquí (http://stackoverflow.com/questions/5286020/python-string -replace-in-a-file-sin-touch-the-file-if-no-substitution-was) – eyquem

Respuesta

34

¿Es posible analizar un archivo línea por línea y editar una línea en el mismo lugar al pasar por las líneas?

Se puede simular usando un archivo de copia de seguridad como lo hace stdlib's fileinput module.

He aquí un ejemplo de script que elimina las líneas que no satisfacen some_condition de los archivos dados en la línea de comandos o 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 finalizar first_file.txt y second_file.txt archivos contendrán solo líneas que satisfacen el predicado some_condition().

+0

Los métodos que realmente no escriben en el medio de un archivo también son acertados porque es fácil hacer la modificación atómica (es decir, el archivo no termina en un estado parcialmente modificado si el programa se interrumpe). – L33tminion

0

Tienes que una copia de seguridad por el tamaño de la línea de caracteres. Suponiendo que use readline, entonces se puede obtener la longitud de la línea y una copia de seguridad usando:

file.seek(offset[, whence]) 

Conjunto de ahí a SEEK_CUR, establecer la compensación a -length.

Consulte Python Docs o consulte la página de manual para seek.

4

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

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

+2

Modo 'rb +' permite leer, mover y escribir en un archivo – eyquem

+1

@eyquem - Buen punto, actualizaré mi respuesta. –

2

Si solo tiene la intención de realizar cambios localizados que no cambian la longitud de la parte del archivo que se modifica (por ejemplo, cambiar todos los caracteres a minúsculas), puede sobrescribir el contenido anterior del archivo de forma dinámica.

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

Alternativamente, usted puede ser capaz de utilizar 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-4 GB en una CPU de 32 bits, dependiendo de su sistema operativo y su configuración.

Cuestiones relacionadas