首页 > 编程 > Python > 正文

python实现的用于搜索文件并进行内容替换的类实例

2020-01-04 18:06:29
字体:
来源:转载
供稿:网友

这篇文章主要介绍了python实现的用于搜索文件并进行内容替换的类,涉及Python针对文件及字符串的相关操作技巧,需要的朋友可以参考下

本文实例讲述了python实现的用于搜索文件并进行内容替换的类。分享给大家供大家参考。具体实现方法如下:

 

 
  1. #!/usr/bin/python -O 
  2. # coding: UTF-8 
  3. ""
  4. -replace string in files (recursive) 
  5. -display the difference. 
  6. v0.2 
  7. - search_string can be a re.compile() object -> use re.sub for replacing 
  8. v0.1 
  9. - initial version 
  10. Useable by a small "client" script, e.g.: 
  11. ------------------------------------------------------------------------------- 
  12. #!/usr/bin/python -O 
  13. # coding: UTF-8 
  14. import sys, re 
  15. #sys.path.insert(0,"/path/to/git/repro/") # Please change path 
  16. from replace_in_files import SearchAndReplace 
  17. SearchAndReplace( 
  18. search_path = "/to/the/files/"
  19. # e.g.: simple string replace: 
  20. search_string = 'the old string'
  21. replace_string = 'the new string'
  22. # e.g.: Regular expression replacing (used re.sub) 
  23. #search_string = re.compile('{% url (.*?) %}'), 
  24. #replace_string = "{% url '/g<1>' %}", 
  25. search_only = True, # Display only the difference 
  26. #search_only = False, # write the new content 
  27. file_filter=("*.py",), # fnmatch-Filter 
  28. ------------------------------------------------------------------------------- 
  29. :copyleft: 2009-2011 by Jens Diemer 
  30. ""
  31. __author__ = "Jens Diemer" 
  32. __license__ = """GNU General Public License v3 or above - 
  33. http://www.opensource.org/licenses/gpl-license.php""" 
  34. __url__ = "http://www.jensdiemer.de" 
  35. __version__ = "0.2" 
  36. import os, re, time, fnmatch, difflib 
  37. # FIXME: see http://stackoverflow.com/questions/4730121/cant-get-an-objects-class-name-in-python 
  38. RE_TYPE = type(re.compile("")) 
  39. class SearchAndReplace(object): 
  40. def __init__(self, search_path, search_string, replace_string, 
  41. search_only=True, file_filter=("*.*",)): 
  42. self.search_path = search_path 
  43. self.search_string = search_string 
  44. self.replace_string = replace_string 
  45. self.search_only = search_only 
  46. self.file_filter = file_filter 
  47. assert isinstance(self.file_filter, (list, tuple)) 
  48. # FIXME: see http://stackoverflow.com/questions/4730121/cant-get-an-objects-class-name-in-python 
  49. self.is_re = isinstance(self.search_string, RE_TYPE) 
  50. print "Search '%s' in [%s]..." % ( 
  51. self.search_string, self.search_path 
  52. print "_" * 80 
  53. time_begin = time.time() 
  54. file_count = self.walk() 
  55. print "_" * 80 
  56. print "%s files searched in %0.2fsec." % ( 
  57. file_count, (time.time() - time_begin) 
  58. def walk(self): 
  59. file_count = 0 
  60. for root, dirlist, filelist in os.walk(self.search_path): 
  61. if ".svn" in root: 
  62. continue 
  63. for filename in filelist: 
  64. for file_filter in self.file_filter: 
  65. if fnmatch.fnmatch(filename, file_filter): 
  66. self.search_file(os.path.join(root, filename)) 
  67. file_count += 1 
  68. return file_count 
  69. def search_file(self, filepath): 
  70. f = file(filepath, "r"
  71. old_content = f.read() 
  72. f.close() 
  73. if self.is_re or self.search_string in old_content: 
  74. new_content = self.replace_content(old_content, filepath) 
  75. if self.is_re and new_content == old_content: 
  76. return 
  77. print filepath 
  78. self.display_plaintext_diff(old_content, new_content) 
  79. def replace_content(self, old_content, filepath): 
  80. if self.is_re: 
  81. new_content = self.search_string.sub(self.replace_string, old_content) 
  82. if new_content == old_content: 
  83. return old_content 
  84. else
  85. new_content = old_content.replace( 
  86. self.search_string, self.replace_string 
  87. if self.search_only != False: 
  88. return new_content 
  89. print "Write new content into %s..." % filepath, 
  90. try
  91. f = file(filepath, "w"
  92. f.write(new_content) 
  93. f.close() 
  94. except IOError, msg: 
  95. print "Error:", msg 
  96. else
  97. print "OK" 
  98. print 
  99. return new_content 
  100. def display_plaintext_diff(self, content1, content2): 
  101. ""
  102. Display a diff. 
  103. ""
  104. content1 = content1.splitlines() 
  105. content2 = content2.splitlines() 
  106. diff = difflib.Differ().compare(content1, content2) 
  107. def is_diff_line(line): 
  108. for char in ("-""+""?"): 
  109. if line.startswith(char): 
  110. return True 
  111. return False 
  112. print "line | text/n-------------------------------------------" 
  113. old_line = "" 
  114. in_block = False 
  115. old_lineno = lineno = 0 
  116. for line in diff: 
  117. if line.startswith(" ") or line.startswith("+"): 
  118. lineno += 1 
  119. if old_lineno == lineno: 
  120. display_line = "%4s | %s" % ("", line.rstrip()) 
  121. else
  122. display_line = "%4s | %s" % (lineno, line.rstrip()) 
  123. if is_diff_line(line): 
  124. if not in_block: 
  125. print "..." 
  126. # Display previous line 
  127. print old_line 
  128. in_block = True 
  129. print display_line 
  130. else
  131. if in_block: 
  132. # Display the next line aber a diff-block 
  133. print display_line 
  134. in_block = False 
  135. old_line = display_line 
  136. old_lineno = lineno 
  137. print "..." 
  138. if __name__ == "__main__"
  139. SearchAndReplace( 
  140. search_path="."
  141. # e.g.: simple string replace: 
  142. search_string='the old string'
  143. replace_string='the new string'
  144. # e.g.: Regular expression replacing (used re.sub) 
  145. #search_string = re.compile('{% url (.*?) %}'), 
  146. #replace_string = "{% url '/g<1>' %}", 
  147. search_only=True, # Display only the difference 
  148. # search_only = False, # write the new content 
  149. file_filter=("*.py",), # fnmatch-Filter 

希望本文所述对大家的Python程序设计有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表