code: def do_action(self, target, dry_run=False):
          
          original_path = os.path.dirname(target)
          original_filename, original_extension = os.path.splitext(os.path.basename(target))
  
          new_filename = re.sub(self.match, self.replace_with, original_filename) + original_extension
          destination = os.path.join(original_path, new_filename)
  
          if dry_run is True:
              self.logger.debug("Dry run: Skipping rename {0} to {1}".format(target, new_filename))
              return target
          else:
              self.logger.debug("Renaming {0} to {1}".format(original_filename + original_extension,
                                                             new_filename + original_extension))
  
              if not os.path.exists(destination):
                  try:
                      shutil.move(target, destination)
                  except IOError:
                      self.logger.error("Error renaming file {0} to {1}".format(target, new_filename))
                      raise IOError
              else:
                  self.logger.error("Destination file already exists: {0}".format(new_filename))
                  raise IOError
  
          return destination
docs: :param target: Full path and filename
          :param dry_run: True - don't actually perform action. False: perform action. No effect for this rule.
          :return: filename: Full path and filename after action completes