-
-
Save csmoore/15e46dedc5604c784b6d to your computer and use it in GitHub Desktop.
| #------------------------------------------------------------------------------ | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| #------------------------------------------------------------------------------ | |
| # Filename: FindAndReplace.py | |
| # Purpose: Simple find and replace string in files (recursive) script | |
| # Usage: python FindAndReplace.py [Old String] [New String] | |
| # [File Filters(ex/default:".txt,.html,.erb")] [Directory To Check] | |
| # Requirement: Files must be text (non-binary) files | |
| # (this is why we force you to pick the file pattern/filter) | |
| # WARNING: This will overwrite files matching [File Filters]. All occurrences of [Old String] | |
| # will be replaced with [New String]. Make sure you really, really want to do this. | |
| #------------------------------------------------------------------------------ | |
| import os | |
| import sys | |
| import traceback | |
| def usage(): | |
| print('Usage: python FindAndReplace.py [Old String] [New String] ' \ | |
| '[File Filters(default:".txt,.html,.erb")] [Directory To Check(.)]') | |
| def replaceStringInFile(fileName, oldStringToReplace, newString): | |
| if not(os.path.isfile(fileName) and os.access(fileName, os.W_OK)): | |
| print("WARNING: Skipping...File does not exist or and is not writeable:" + fileName) | |
| return False | |
| fileUpdated = False | |
| # credit/taken/adapted from: http://stackoverflow.com/a/4128194 | |
| # Read in old file | |
| with open(fileName, 'r') as f: | |
| newlines = [] | |
| for line in f.readlines(): | |
| if (oldStringToReplace in line) : | |
| fileUpdated = True | |
| line = line.replace(oldStringToReplace, newString) | |
| newlines.append(line) | |
| # Write changes to same file | |
| if fileUpdated : | |
| print("String Found and Updating File: " + fileName) | |
| try: | |
| with open(fileName, 'w') as f: | |
| for line in newlines: | |
| f.write(line) | |
| except: | |
| print('ERROR: Cannot open/access existing file for writing: ' + fileName) | |
| return fileUpdated | |
| def main(): | |
| try: | |
| DEFAULT_PATH = '.' | |
| if len(sys.argv) < 3: | |
| usage() | |
| # old/new string required parameters, exit if not supplied | |
| sys.exit(-1) | |
| else: | |
| oldString = sys.argv[1] | |
| newString = sys.argv[2] | |
| if len(sys.argv) < 4: | |
| patterns = ['.txt', '.html', '.erb'] | |
| else: | |
| stringFilter = sys.argv[3] | |
| patterns = stringFilter.split(',') | |
| if len(sys.argv) < 5: | |
| path = DEFAULT_PATH | |
| else: | |
| path = sys.argv[4] | |
| print('[Old String] : ' + oldString) | |
| print('[New String] : ' + newString) | |
| print('[File Filters] : ' + ', '.join(patterns)) | |
| print('[Directory To Check] : ' + path) | |
| if not os.path.exists(path): | |
| raise Exception("Selected path does not exist: " + path) | |
| # Walks through directory structure looking for files matching patterns | |
| matchingFileList = \ | |
| [os.path.join(dp, f) \ | |
| for dp, dn, filenames in os.walk(path) \ | |
| for f in filenames \ | |
| if os.path.splitext(f)[1] in patterns] | |
| print('Files found matching patterns: ' + str(len(matchingFileList))) | |
| fileCount = 0 | |
| filesReplaced = 0 | |
| for currentFile in matchingFileList: | |
| fileCount+=1 | |
| fileReplaced = replaceStringInFile(currentFile, oldString, newString) | |
| if fileReplaced: | |
| filesReplaced+=1 | |
| print("Total Files Searched : " + str(fileCount)) | |
| print("Total Files Replaced/Updated : " + str(filesReplaced)) | |
| except Exception as err: | |
| print(traceback.format_exception_only(type(err), err)[0].rstrip()) | |
| sys.exit(-1) | |
| if __name__ == '__main__': | |
| main() |
So I was able to get the script to work. I have to add encoding for the read and write phases. And I went from 1174 ocurances of the OldString down to 11. And those are embedded into some xml tags. For which I just did a find/replace in Notepad++ as I wanted to get this script to my teammate.
Thanks!!
Glad you were able to get something working - I guess Notepad++ is indeed another option if it is a non-batch case - but then you never get the fun of learning to work with unicode
Ok so now you are being evil :) Putting a link to what seems to be a well crafted article on Unicode, gets me reading about it. And wanting to then use it. Almost like a real, grown up programmer. Which I am not by trade but am getting into more and more.
Thanks for the link. And for this script!
Hi
I tried to use your program to work with .xml file, and I am getting error. If possible plz check the below stackoverflow link for my query
For a large file - I would probably restructure this script to read/write one line at a time.