2010-06-24 20 views
5

Me gustaría aprender a utilizar Python como reemplazo de scripts de línea de comandos. Pasé un tiempo con Python en el pasado, pero ha pasado un tiempo. Esto parece estar dentro del alcance de esto.Haga una búsqueda y reemplazo en todos los archivos en una carpeta a través de python?

Tengo varios archivos en una carpeta en la que quiero hacer una búsqueda y reemplazo, dentro de todos ellos. Me gustaría hacerlo con un script de Python.

Por ejemplo, busque y reemplace todas las instancias de "foo" con "foobar".

Respuesta

2

Normalmente me látigo de la vieja perl -pi -e 's/foo/foobar/' para esto, pero si quieres Python:

import os 
import re 
_replace_re = re.compile("foo") 
for dirpath, dirnames, filenames in os.walk("directory/"): 
    for file in filenames: 
     file = os.path.join(dirpath, file) 
     tempfile = file + ".temp" 
     with open(tempfile, "w") as target: 
      with open(file) as source: 
       for line in source: 
        line = _replace_re.sub("foobar", line) 
        target.write(line) 
     os.rename(tempfile, file) 

Y si estás en Windows, tendrá que añadir una os.remove(file) antes de la os.rename(tempfile, file).

+0

También, podría ser bueno para poner en una pequeña comprobación para verificar que el 'tempfile' no existe ya ... –

+0

Esto parece tener sentido. ¿Es el acto de crear el archivo temporal solo si los permisos no son suficientes, aún podemos realizar la acción? En ese caso, la eliminación y el cambio de nombre tampoco funcionarán, ¿correcto? – fruit

+0

El archivo temporal se asegura de que no sobrescribamos el archivo real demasiado pronto y de modo que no agotemos mucha memoria en un archivo grande (la forma más fácil de hacerlo sería algo como: 'data = open (file) .read(); data = _replace_re.sub ("foobar", data); open (archivo, "w"). write (data) ', pero eso usaría mucha memoria y, si la computadora se estrelló a la mitad la 'escritura', perdería los datos no escritos) –

1

Lo he trabajado y parece que funciona, pero cualquier error que se pueda señalar sería increíble.

import fileinput, sys, os 

def replaceAll(file, findexp, replaceexp): 
    for line in fileinput.input(file, inplace=1): 
     if findexp in line: 
      line = line.replace(findexp, replaceexp) 
     sys.stdout.write(line) 

if __name__ == '__main__': 
    files = os.listdir("c:/testing/") 
    for file in files: 
     newfile = os.path.join("C:/testing/", file) 
     replaceAll(newfile, "black", "white") 

una expansión en esto sería mover las carpetas dentro de las carpetas.

+0

Lo que podría querer hacer es cambiar eso a 'replaceAll (file," black "," white ")' - como está si alguna vez tiene 'somedir/blackdir/blackfile.txt' luego obtendrás 'somedir/whitedir/whitefile.txt'.A menos, por supuesto, que quieras eso, en cuyo caso déjalo tal como lo tienes. –

+0

¿Por qué esta función cambia el nombre de los archivos? Lo está buscando línea por línea. – fruit

5

Bienvenido a StackOverflow. Como quiera aprender usted mismo (+1) solo le daré algunos consejos.

Consulte os.walk() para obtener todos los archivos.

Luego itere sobre cada línea en los archivos (for line in currentfile: es útil aquí).

Ahora lo que necesita saber si desea una "estúpida" replace (buscar/reemplazar cada foo incluso si es en el medio de una palabra (por ejemplo foobar - ¿Quieres foofoobar como resultado) o reemplazar un inteligente?.

en el primer caso, mira str.replace(), para este último, mira re.sub() y averiguar qué r'\bfoo\b' medios.

+0

¡Muy bien, gracias! Aprender sobre nuevas funciones (os.walk()) siempre es bueno. ¿Atraviesa subdirectorios, también? Supongo que su enlace me dirá. – fruit

+0

Sí, lo hace, y sí lo hace :) –

0

esta es una alternativa, ya que tiene varias soluciones de Python que se le presenten. la utilidad más útil (según yo), en Unix/Windows, el GNU encuentra herramientas de comando y reemplazo como sed/awk. para buscar f iles (recursivamente) y hacer el reemplazo, un simple comando como este hace el truco (la sintaxis viene de la memoria y no se prueba). esto dice encontrar todos los archivos de texto y cambiar la palabra "viejo" a "nuevo" en su contenido, al mismo tiempo, utilizar sed hacer copias de seguridad de los archivos originales ...

$ find /path -type f -iname "*.txt" -exec sed -i.bak 's/old/new/g' "{}" +; 
Cuestiones relacionadas