Changing strings in files

Mike Dewhirst miked at dewhirst.com.au
Tue Nov 10 02:52:26 EST 2020


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))


  





-- 
Signed email is an absolute defence against phishing. This email has
been signed with my private key. If you import my public key you can
automatically decrypt my signature and be sure it came from me. Just
ask and I'll send it to you. Your email software can handle signing.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 495 bytes
Desc: OpenPGP digital signature
URL: <https://mail.python.org/pipermail/python-list/attachments/20201110/80c49d2f/attachment.sig>


More information about the Python-list mailing list