Skip to content

Instantly share code, notes, and snippets.

@tvdsluijs
Created February 26, 2019 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tvdsluijs/fbc937d1a1e90f5d6746794065230ade to your computer and use it in GitHub Desktop.
Save tvdsluijs/fbc937d1a1e90f5d6746794065230ade to your computer and use it in GitHub Desktop.
Search and replace text within files within a folder.
'''
author: Pure Python
url: https://www.purepython.org
copyright: CC BY-NC 4.0
creation date: 26-02-2019
With this script you can search within a folder and files for some text and replace it with other text.
Extra install:
For the fun of it I used the Halo spinner package to show a nice progress spinner
pip install Halo
'''
import os
import re
from glob import iglob
from halo import Halo
class SearchFiles:
def __init__(self):
self.tfe = ['.txt', '.php', '.py', '.cvs', '.log', '.doc', '.dat', '.xml', '.json', '.css',
'.js', '.md', '.htm', '.html', '.asp', '.aspx', '.jsp', '.rss', '.xhtml', '.sh', '.bak']
self.spinner = Halo(text='', spinner='dots', color='blue')
self.start_folder = ""
self.search_text = ""
self.text_files = ""
self.foundfileslist = []
yesno = ['Y', 'N']
answer = ""
while answer not in yesno:
answer = input("Did you create a backup? When things go wrong, all files will me broken! {} ".format(str(yesno)))
while self.start_folder == "":
self.start_folder = input("What folder do you want to start? ")
while self.search_text == "":
self.search_text = input("What do you want to search for? ")
self.replace_text = None
answer = ""
while answer not in yesno:
answer = input("Do you want to replace the text? {} ".format(str(yesno)))
if answer == 'Y':
self.replace_text = input("What do you want it to replace with? ")
if self.replace_text == "":
self.replace_text = None
answer = ""
while answer not in yesno:
self.text_files = input("Text files only? {} ".format(str(yesno)))
self.getfilelist()
self.processfiles()
for f in self.foundfileslist:
print(f)
def getfilelist(self):
self.spinner.start('Start loading files')
rootdir_glob = "{}/**/*".format(self.start_folder) # Note the added asterisks
# This will return absolute paths
# '**/*'
if self.text_files == 'Y':
self.file_list = [f for f in iglob(rootdir_glob, recursive=True) if
os.path.isfile(f) and os.path.splitext(f)[1] in self.tfe]
else:
self.file_list = [f for f in iglob(rootdir_glob, recursive=True) if
os.path.isfile(f)]
self.spinner.succeed('Files Loaded')
def processfiles(self):
self.spinner.start('Start search in files')
for file in self.file_list:
result_new = None
if self.replace_text is not None:
try:
f = open(file, 'r')
content = f.read()
f.close()
result = re.search(r"{}".format(self.search_text), content, flags=re.M)
if result:
result.group(0)
else:
continue
result_new = re.sub(r"{}".format(self.search_text), r"{}".format(self.replace_text), content,
flags=re.M)
if result_new != "" and result_new is not None:
f_out = open(file, 'w')
f_out.write(result_new)
f_out.close()
self.foundfileslist.append("{} : REPLACED".format(file))
else:
self.foundfileslist.append("{} : error found".format(file))
continue
except KeyError as e:
#next file
self.foundfileslist.append("{} : search string not Found".format(file))
continue
except UnicodeDecodeError as e:
self.foundfileslist.append("{} : {e}".format(file, e))
continue
except Exception as e:
#next file
self.foundfileslist.append("{} : {e}".format(file, e))
continue
else:
try:
with open(file, 'r') as f:
i = 0
for line in f:
i += 1
try:
result = re.search(r"{}".format(self.search_text), line).group(0)
self.foundfileslist.append("{} : line {}".format(file, i))
except:
continue
except UnicodeDecodeError as e:
print(e)
continue
self.spinner.succeed('Files search done')
if __name__ == "__main__":
s = SearchFiles()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment