45fan.com - 路饭网

搜索: 您的位置主页 > 网络频道 > 阅读资讯:python搜索文件并替换内容的类分享

python搜索文件并替换内容的类分享

2015-07-21 20:34:52 来源:www.45fan.com 【

python搜索文件并替换内容的类分享

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

#!/usr/bin/python -O
# coding: UTF-8
"""
-replace string in files (recursive)
-display the difference.
v0.2
 - search_string can be a re.compile() object -> use re.sub for replacing
v0.1
 - initial version
 Useable by a small "client" script, e.g.:
-------------------------------------------------------------------------------
#!/usr/bin/python -O
# coding: UTF-8
import sys, re
#sys.path.insert(0,"/path/to/git/repro/") # Please change path
from replace_in_files import SearchAndReplace
SearchAndReplace(
 search_path = "/to/the/files/",
 # e.g.: simple string replace:
 search_string = 'the old string',
 replace_string = 'the new string',
 # e.g.: Regular expression replacing (used re.sub)
 #search_string = re.compile('{% url (.*?) %}'),
 #replace_string = "{% url '\g<1>' %}",
 search_only = True, # Display only the difference
 #search_only = False, # write the new content
 file_filter=("*.py",), # fnmatch-Filter
)
-------------------------------------------------------------------------------
:copyleft: 2009-2011 by Jens Diemer
"""
__author__ = "Jens Diemer"
__license__ = """GNU General Public License v3 or above -
 http://www.opensource.org/licenses/gpl-license.php"""
__url__ = "http://www.jensdiemer.de"
__version__ = "0.2"
import os, re, time, fnmatch, difflib
# FIXME: see http://stackoverflow.com/questions/4730121/cant-get-an-objects-class-name-in-python
RE_TYPE = type(re.compile(""))
class SearchAndReplace(object):
 def __init__(self, search_path, search_string, replace_string,
          search_only=True, file_filter=("*.*",)):
  self.search_path = search_path
  self.search_string = search_string
  self.replace_string = replace_string
  self.search_only = search_only
  self.file_filter = file_filter
  assert isinstance(self.file_filter, (list, tuple))
  # FIXME: see http://stackoverflow.com/questions/4730121/cant-get-an-objects-class-name-in-python
  self.is_re = isinstance(self.search_string, RE_TYPE)
  print "Search '%s' in [%s]..." % (
   self.search_string, self.search_path
  )
  print "_" * 80
  time_begin = time.time()
  file_count = self.walk()
  print "_" * 80
  print "%s files searched in %0.2fsec." % (
   file_count, (time.time() - time_begin)
  )
 def walk(self):
  file_count = 0
  for root, dirlist, filelist in os.walk(self.search_path):
   if ".svn" in root:
    continue
   for filename in filelist:
    for file_filter in self.file_filter:
     if fnmatch.fnmatch(filename, file_filter):
      self.search_file(os.path.join(root, filename))
      file_count += 1
  return file_count
 def search_file(self, filepath):
  f = file(filepath, "r")
  old_content = f.read()
  f.close()
  if self.is_re or self.search_string in old_content:
   new_content = self.replace_content(old_content, filepath)
   if self.is_re and new_content == old_content:
    return
   print filepath
   self.display_plaintext_diff(old_content, new_content)
 def replace_content(self, old_content, filepath):
  if self.is_re:
   new_content = self.search_string.sub(self.replace_string, old_content)
   if new_content == old_content:
    return old_content
  else:
   new_content = old_content.replace(
    self.search_string, self.replace_string
   )
  if self.search_only != False:
   return new_content
  print "Write new content into %s..." % filepath,
  try:
   f = file(filepath, "w")
   f.write(new_content)
   f.close()
  except IOError, msg:
   print "Error:", msg
  else:
   print "OK"
  print
  return new_content
 def display_plaintext_diff(self, content1, content2):
  """
  Display a diff.
  """
  content1 = content1.splitlines()
  content2 = content2.splitlines()
  diff = difflib.Differ().compare(content1, content2)
  def is_diff_line(line):
   for char in ("-", "+", "?"):
    if line.startswith(char):
     return True
   return False
  print "line | text\n-------------------------------------------"
  old_line = ""
  in_block = False
  old_lineno = lineno = 0
  for line in diff:
   if line.startswith(" ") or line.startswith("+"):
    lineno += 1
   if old_lineno == lineno:
    display_line = "%4s | %s" % ("", line.rstrip())
   else:
    display_line = "%4s | %s" % (lineno, line.rstrip())
   if is_diff_line(line):
    if not in_block:
     print "..."
     # Display previous line
     print old_line
     in_block = True
    print display_line
   else:
    if in_block:
     # Display the next line aber a diff-block
     print display_line
    in_block = False
   old_line = display_line
   old_lineno = lineno
  print "..."
if __name__ == "__main__":
 SearchAndReplace(
  search_path=".",
  # e.g.: simple string replace:
  search_string='the old string',
  replace_string='the new string',
  # e.g.: Regular expression replacing (used re.sub)
  #search_string = re.compile('{% url (.*?) %}'),
  #replace_string = "{% url '\g<1>' %}",
  search_only=True, # Display only the difference
#  search_only  = False, # write the new content
  file_filter=("*.py",), # fnmatch-Filter
 )

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


本文地址:http://www.45fan.com/a/question/15260.html
Tags: 实现 python 搜索
编辑:路饭网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部