On Tue, 10 Nov 2020 18:52:26 +1100 Mike Dewhirst <mi...@dewhirst.com.au> wrote:
> On 10/11/2020 5:24 pm, Manfred Lotz wrote: > > I have a situation where in a directory tree I want to change a > > certain string in all files where that string occurs. > > > > My idea was to do > > > > - os.scandir and for each file > > - check if a file is a text file > > - if it is not a text file skip that file > > - change the string as often as it occurs in that file > > > > > > What is the best way to check if a file is a text file? In a script > > I could use the `file` command which is not ideal as I have to grep > > the result. In Perl I could do -T file. > > > > How to do best in Python? > Not necessarily best but I rolled this earlier. Much earlier. But I > still use it. I don't need to worry about text files or binary > because I specify .py files. > > > > # -*- coding: utf-8 -*- > """ > Look for string 'find' and replace it with string 'repl' in all files > in the current directory and all sub-dirs. > > If anything untoward happens, laboriously retrieve each original file > from each individual backup made by suffixing ~ to the filename. > > If everything went well, make find == repl and run again to remove > backups. > > """ > import os > > find = """# Copyright (c) 2019 Xyz Pty Ltd""" > > repl = """# Copyright (c) 2020 Xyz Pty Ltd""" > > ii = 0 > kk = 0 > for dirpath, dirnames, filenames in os.walk(".", topdown=True): > if "migrations" in dirpath: > continue > for filename in filenames: > if filename.endswith(".py"): # or filename.endswith(".txt"): > fil = os.path.join(dirpath, filename) > bak = "{0}~".format(fil) > if find == repl: > if os.path.isfile(bak): > ii += 1 > os.remove(bak) > else: > with open(fil, "r") as src: > lines = src.readlines() > # make a backup file > with open(bak, "w", encoding="utf-8") as dst: > for line in lines: > dst.write(line) > with open(bak, "r") as src: > lines = src.readlines() > # re-write the original src > with open(fil, "w", encoding="utf-8") as dst: > kk += 1 > for line in lines: > dst.write(line.replace(find, repl)) > print("\nbak deletions = %s, tried = %s\n" % (ii, kk)) > > Thanks, will take a look. -- Manfred -- https://mail.python.org/mailman/listinfo/python-list