Python - Way to recursively find and replace string in text files

后端 未结 9 2347
小蘑菇
小蘑菇 2020-12-24 01:56

I want to recursively search through a directory with subdirectories of text files and replace every occurrence of {$replace} within the files with the contents of a multi l

相关标签:
9条回答
  • 2020-12-24 02:33

    How about just using:

    clean = ''.join([e for e in text if e != 'string'])
    
    0 讨论(0)
  • 2020-12-24 02:36

    Sulpy's answer is good but incomplete. The user would be likely to want to input the parameters through an entry widget, so we might have something more like this (also incomplete, but left as an exercise):

    import os, fnmatch
    from Tkinter import *
    fields = 'Folder', 'Search', 'Replace', 'FilePattern'
    
    def fetch(entvals):
    #    print entvals
    #    print ents
        entItems = entvals.items()
        for entItem in entItems:
            field = entItem[0]
            text  = entItem[1].get()
            print('%s: "%s"' % (field, text))
    
    def findReplace(entvals):
    #    print ents
        directory = entvals.get("Folder").get()
        find = entvals.get("Search").get()
        replace = entvals.get("Replace").get()
        filePattern = entvals.get("FilePattern").get()
        for path, dirs, files in os.walk(os.path.abspath(directory)):
            for filename in fnmatch.filter(files, filePattern):
    #            print filename
                filepath = os.path.join(path, filename)
                print filepath  # Can be commented out --  used for confirmation
                with open(filepath) as f:
                    s = f.read()
                s = s.replace(find, replace)
                with open(filepath, "w") as f:
                    f.write(s)
    
    def makeform(root, fields):
        entvals = {}
        for field in fields:
            row = Frame(root)
            lab = Label(row, width=17, text=field+": ", anchor='w')
            ent = Entry(row)
            row.pack(side=TOP, fill=X, padx=5, pady=5)
            lab.pack(side=LEFT)
            ent.pack(side=RIGHT, expand=YES, fill=X)
            entvals[field] = ent
    #        print ent
        return entvals
    
    if __name__ == '__main__':
        root = Tk()
        root.title("Recursive S&R")
        ents = makeform(root, fields)
    #    print ents
        root.bind('<Return>', (lambda event, e=ents: fetch(e)))
        b1 = Button(root, text='Show', command=(lambda e=ents: fetch(e)))
        b1.pack(side=LEFT, padx=5, pady=5)
        b2 = Button(root, text='Execute', command=(lambda e=ents: findReplace(e)))
        b2.pack(side=LEFT, padx=5, pady=5)
        b3 = Button(root, text='Quit', command=root.quit)
        b3.pack(side=LEFT, padx=5, pady=5)
        root.mainloop()
    
    0 讨论(0)
  • 2020-12-24 02:40

    Here's my code (which I think is the same as the above but I'm including it just in case there's something subtly different about it):

    import os, fnmatch, sys
    def findReplace(directory, find, replace, filePattern):
        for path, dirs, files in os.walk(os.path.abspath(directory)):
            for filename in fnmatch.filter(files, filePattern):         
                filepath = os.path.join(path, filename)
                with open(filepath) as f:
                    s = f.read()
                s = s.replace(find, replace)
                with open(filepath, "w") as f:
                    f.write(s)
    

    it runs without error. BUT, the file, in z:\test is unchanged. I've put in print statements, like print("got here") but they don't print out either.

    0 讨论(0)
  • 2020-12-24 02:42

    Multiple files string change

    import glob

    for allfiles in glob.glob('*.txt'):

    for line in open(allfiles,'r'):
        change=line.replace("old_string","new_string")
        output=open(allfiles,'w')
        output.write(change)    
    
    0 讨论(0)
  • 2020-12-24 02:44

    For those using Python 3.5+ you can now use a glob recursively with the use of ** and the recursive flag.

    Here's an example replacing hello with world for all .txt files:

    for filepath in glob.iglob('./**/*.txt', recursive=True):
        with open(filepath) as file:
            s = file.read()
        s = s.replace('hello', 'world')
        with open(filepath, "w") as file:
            file.write(s)
    
    0 讨论(0)
  • 2020-12-24 02:47

    os.walk is great. However, it looks like you need to filer file types (which I would suggest if you are going to walk some directory). To do this, you should add import fnmatch.

    import os, fnmatch
    def findReplace(directory, find, replace, filePattern):
        for path, dirs, files in os.walk(os.path.abspath(directory)):
            for filename in fnmatch.filter(files, filePattern):
                filepath = os.path.join(path, filename)
                with open(filepath) as f:
                    s = f.read()
                s = s.replace(find, replace)
                with open(filepath, "w") as f:
                    f.write(s)
    

    This allows you to do something like:

    findReplace("some_dir", "find this", "replace with this", "*.txt")
    
    0 讨论(0)
提交回复
热议问题