reemplazar TODAS las instancias de un personaje con otro en todos los archivos jerárquicamente en el árbol de directorios

so the command line will look like :

./replace.py

current directory may be /home/user before = "\" after = '/"

which means replacing backslash with / forward slash in ALL files. Now the ONLY place where this replacement takes place is when the LINE contains text "path"

here is what i have , which actually does replace text, but not / , or \

#!/usr/bin/python
import os
import re
import sys

#print f.readline().replace('\\','/')
#replace_extensions = []
replace_extensions = [".tst"]

def try_to_replace(fname):
    if replace_extensions:
        return fname.lower().endswith(replace_extensions)
    return True


def file_replace(fname, pat, s_after):
    with open(fname) as f:
        if not any(re.search(pat, line) for line in f):
            return

    with open(fname) as f:
        out_fname = fname + ".tmp"
        out = open(out_fname, "w")
        for line in f:
            out.write(re.sub(pat, s_after, line))
        out.close()
        os.rename(out_fname, fname)


def mass_replace(dir_name, s_before, s_after):
    pat = re.compile(s_before)
    for dirpath, dirnames, filenames in os.walk(dir_name):
        for fname in filenames:
            if try_to_replace(fname):
                fullname = os.path.join(dirpath, fname)
                file_replace(fullname, pat, s_after)

if len(sys.argv) != 4:
    u = "Usage: mass_replace <dir_name> <string_before> <string_after>\n"
    sys.stderr.write(u)
    sys.exit(1)

mass_replace(sys.argv[1], sys.argv[2], sys.argv[3])

y me sale un error:

./mass_replace.py test1 '\\' '/'
Traceback (most recent call last):
  File "./mass_replace.py", line 43, in <module>
    mass_replace(sys.argv[1], sys.argv[2], sys.argv[3])
  File "./mass_replace.py", line 34, in mass_replace
    if try_to_replace(fname):
  File "./mass_replace.py", line 12, in try_to_replace
    return fname.lower().endswith(replace_extensions)
TypeError: expected a character buffer object

preguntado el 31 de julio de 12 a las 13:07

1 Respuestas

El problema es que str.endswith expects a string; you're passing a list. Try

return any(fname.lower().endswith(extension) for extension in replace_extensions)

Actually, it would be better to use os.path.splitext:

return os.path.splitext(fname.lower())[1] in replace_extensions

Otherwise your code looks fine, although you'd do well to use a with expression for the output file as well:

    with open(out_fname, "w") as out:
        for line in f:
            out.write(re.sub(pat, s_after, line))

Respondido 31 Jul 12, 14:07

Thanks @ecatmur, is there a way i can use / and \ (forward and backslash ) as before nad replace chars ? i try ./mass_replace.py test1 '\' '/' and get "sre_constants.error: bogus escape (end of line)" - kamal

OOps, my bad, i forgot to escape \ :) - kamal

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.