Deprecating php's regRename, migrating to python

This commit is contained in:
斟酌 鵬兄 2017-12-01 13:15:37 +08:00
parent 61c985e1b0
commit 8a828cdf34
3 changed files with 168 additions and 272 deletions

View File

@ -1,225 +0,0 @@
<?php
namespace astropenguin\botanical;
use DirectoryIterator;
class RegRename
{
//Define globals
private $test = false;
private $recursive = false;
private $searchDirs = array();
private $patterns = array();
private $replaceStrs = array();
private $excludes = array();
private $logfile = NULL;
public function begin()
{
$this->validateOptions();
//------- Begin Operations -------
foreach ( $this->searchDirs as $dir )
{
$this->elog("Directory: $dir\nBuilding file list ...");
if ( $this->recursive )
{
$fileList = $this->getWholeFileList($dir);
}
else
{
$fileList = $this->getFileList($dir);
}
$this->elog("Searching ...");
foreach ( $fileList as $file )
{
//
// Get the file name
// RegExplained:
// Example: /foo/bar/foobar.bar
// $matches[0][0] is the whole string "/foo/bar/foobar.bar"
//
// ^(.+?)
// This gets the file path "/foo/bar/" for $matches[1][0]
//
// ([^\/\\\\]+)$
// This gets the file name "foobar.bar" for $matches[2][0]
//
preg_match_all('/^(.+?)([^\/\\\\]+)$/', $file, $matches );
$newName = $matches[2][0];
foreach ( $this->patterns as $key => $pattern )
{
//Rename over the patterns
$newName = preg_replace( $pattern, $this->replaceStrs[$key], $newName );
}
if( $matches[2][0] != $newName )
{
// Excluede any matches
foreach ( $this->excludes as $key => $pattern )
{
if(preg_match_all($pattern, $file))
{
$this->elog("S File \"{$matches[2][0]}\" excluded on $pattern");
continue 2;
}
}
if( $this->test )
{
$this->elog("R File \"{$matches[2][0]}\" will be renamed to \"$newName\"");
}
else
{
rename ( $file, "{$matches[1][0]}$newName" );
}
if( $this->logfile )
{
file_put_contents( $this->logfile, $this->log );
}
}
/*
else
{
echo "File \"{$matches[0][0]}\" will not be renamed\n";
}
//*/
}
$this->elog();
}
if ( $this->test ) $this->elog("*** Test enabled ***\n");
//------- End Operations -------*/
}
public function setOption( $item, $value = NULL )
{
switch($item)
{
case "-d":
if($value)
$this->searchDirs[] = $value;
break;
case "-p":
if($value)
$this->patterns[] = $value;
break;
case "-r":
$this->recursive = true;
break;
case "-s":
if($value)
$this->replaceStrs[] = $value;
break;
case "-t":
$this->test = true;
break;
case "-e":
$this->excludes[] = $value;
break;
case "-l":
$this->logfile = $value;
break;
default:
//Do nothing
}
}
//------- Main Functions --------
function elog( $line = "" )
{
$this->log .= $line;
$this->log .= "\n";
echo "$line\n";
}
private function getDirName ( $dir )
{
return is_dir ( $dir ) ? $dir : dirname ( $dir ) ;
}
private function getFileList ( $dir )
{
$fileList = array();
$iterator = new DirectoryIterator ( $this->getDirName ( $dir ) ) ;
foreach ( $iterator as $fileinfo )
{
if ( $fileinfo->isFile() )
{
$fileList[] = $dir."/".$fileinfo->getFilename();
}
}
return $fileList;
}
private function getDirList ( $dir )
{
$dirList = array();
$iterator = new DirectoryIterator ( $this->getDirName ( $dir ) );
foreach ( $iterator as $fileinfo )
{
if ( $fileinfo->isDir() && !$fileinfo->isDot())
{
$dirList[] = $fileinfo->getFilename();
}
}
return $dirList;
}
private function getWholeDirList ( $dir )
{
$wholeDirList = array();
//getWholeDirList will stop untill getDirList return an empty array.
foreach ( $this->getDirList ( $dir ) as $file )
{
//Store found path
$wholeDirList[] = "$dir/$file";
//Method getWholeDirList will self-iterate if sub-directories exist.
$wholeDirList = array_merge ( $wholeDirList, $this->getWholeDirList ( "$dir/$file" ) ) ;
}
return $wholeDirList;
}
private function getWholeFileList ( $dir )
{
//Get the first level list.
$wholeFileList = $this->getFileList( $dir );
//getWholeDirList and search its files.
foreach ( $this->getWholeDirList ( $dir ) as $dir )
{
$wholeFileList = array_merge ( $wholeFileList, $this->getFileList ( $dir ) ) ;
}
return $wholeFileList;
}
private function validateOptions ( )
{
try
{
if(count($this->searchDirs) == 0)
throw new \Exception("Search directory is missing");
else if(count($this->patterns) == 0)
throw new \Exception("Search pattern is missing");
else if(count($this->replaceStrs) == 0)
throw new \Exception("Replacement string is missing");
else if(count($this->replaceStrs) != count($this->patterns))
throw new \Exception("Replacement string and pattern count not match");
}
catch( \Exception $e )
{
var_dump( $GLOBALS );
die("Error: $e.\n");
}
}
//------- End Main Functions --------
}

View File

@ -1,47 +0,0 @@
#!/usr/bin/env php
<?php
error_reporting ( E_ALL^E_NOTICE ) ;
require_once dirname( __FILE__ ) . '/astropenguin/package.php';
use astropenguin\botanical\RegRename;
use astropenguin\botanical\Args;
//----------- Usage -----------
if ( !$argv[1] )
die (<<<__USAGE__
Usage: php {$argv[0]} [options] [-d directory] [-p patterns] [-s "first match" "second" ...] [...args]
-d <paths> Directories to look over
-p <patterns> Define RegEx patterns
-r Rename file recursively
-s <str ...> Strings that will replace the matches
Optional:
-e <patterns> Exclude defined pattern
-l <File> Output log file
-t Test without modifying anything
Example:
php regRename.php -d ~/ -p "/(.+)_.+/" -s "\\1"
Result:
R File ".mysql_history" will be renamed to ".mysql"
R File ".db_pass" will be renamed to ".db"
R File ".bash_logout" will be renamed to ".bash"
R File ".mysql_pass" will be renamed to ".mysql"
R File ".bash_history" will be renamed to ".bash"
php regRename.php -d ~/ -p "/(.+)_.+/" -s "\\1"
__USAGE__
) ;
//------- End Usage -----------
$rrgr = new RegRename();
Args::PARSE ( $argv, array($rrgr, 'setOption') );
$rrgr->begin();

168
python/reg-rename.py Normal file
View File

@ -0,0 +1,168 @@
#!/bin/env python3
import argparse, os, re, sys
# {{{ Argument Parsing
parser = argparse.ArgumentParser(
description = "Tools for renaming files using regular expressions"
, formatter_class = argparse.RawDescriptionHelpFormatter
, epilog = """
Example:
%(prog)s -d ~/ -p "/(.+)_.+/" -s "\\1"
Result:
R ".mysql_history" will be renamed to ".mysql"
R ".db_pass" will be renamed to ".db"
R ".bash_logout" will be renamed to ".bash"
R ".mysql_pass" will be renamed to ".mysql"
R ".bash_history" will be renamed to ".bash"
"""
)
parser.add_argument( "-r", action = "store_true", help = "Rename files recursively" )
parser.add_argument( "-d", required = True, metavar = "dirs", nargs = "+", help = "Directories to look over" )
parser.add_argument( "-p", required = True, metavar = "patterns", nargs = "+" , help = "Include patterns")
parser.add_argument( "-s", required = True, metavar = "substitudes", nargs = "+", help = "Strings that will replace the matches" )
parser.add_argument( "-e", metavar = "patterns", nargs = "+", help = "Exclude patterns" )
parser.add_argument( "-t", action = "store_true", help = "Test without modifying anything" )
# End Argement Parsing }}}
args = parser.parse_args()
class ArgumentRequired( Exception ): pass
class InvalidArgument( Exception ): pass
class LevelLogger:
lv = 0
def __init__( self, level ):
self.lv = level
self.pad = " " * level
def log( self, mesg ):
print( self.pad + mesg )
def log_all( self, mesgs ):
for mesg in mesgs:
self.log( mesg )
class LoggerSpawner:
lv = 0
def __enter__( self ):
self.lv = self.lv + 1
return LevelLogger( self.lv )
def __exit__( self, *args ):
self.lv = self.lv - 1
class RAction:
def __init__( self, root, _from, _to, exclude ):
self.root = root
self._from = _from
self._to = _to
self.exc = exclude
def run( self, test ):
root, _from, _to = self.root, self._from, self._to
if self.exc:
return "= Excluding \"%s\"" % _from
if test:
return "R \"%s\" will be renamed to \"%s\"" % ( _from, _to )
else:
os.rename( os.path.join( root, _from ), os.path.join( root, _to ) )
return "R \"%s\" -> \"%s\"" % ( _from, _to )
class RegReplace:
def __init__( self, includes, replacements, excludes, recursive ):
self.logger = LoggerSpawner()
self.recursive = recursive
self.includes = includes
self.excludes = excludes
self.subs = replacements
self.test = False
def _exclude( self, k ):
for ex in self.excludes:
if ex.match( k ):
return True
return False
def _compile_actions( self, root, files ):
rlist = []
for file_name in files:
for i, p in enumerate( self.includes ):
if p.match( file_name ):
if self._exclude( file_name ):
rlist.append( RAction( root, file_name, file_name, True ) )
else:
sub = self.subs[ i ]
k = p.sub( sub, file_name )
rlist.append( RAction( root, file_name, k, False ) )
return rlist
def searchDirs( self, path ):
bb = "-\\|/"
bb_i = 0
for root, dirs, files in os.walk( path ):
actions = self._compile_actions( root, files )
sys.stdout.write( bb[ bb_i ] )
sys.stdout.flush()
sys.stdout.write( "\b" )
bb_i = bb_i + 1
if 3 < bb_i:
bb_i = 0
if actions:
with self.logger as DirLogger:
DirLogger.log( "In directory: \"%s\"" % root )
with self.logger as ActionLogger:
for action in actions:
mesg = action.run( self.test )
ActionLogger.log( mesg )
if not self.recursive:
break
sys.stdout.write( " " )
sys.stdout.flush()
def _compile_re( patterns ):
_list = []
if patterns:
for p in patterns:
if not ( p[0] == p[-1] == "/" ):
raise InvalidArgument( p )
_list.append( re.compile( p[ 1:-1 ] ) )
return _list
try:
includes = _compile_re( args.p )
excludes = _compile_re( args.e )
if not args.d:
raise ArgumentRequired( "-d" )
if args.t:
print( "** Test Mode" )
reg_replace = RegReplace( includes, args.s, excludes, args.r )
reg_replace.test = args.t
for _dir in args.d:
reg_replace.searchDirs( _dir )
except InvalidArgument as ex:
print( "Invalid argument: %s" % ex )
sys.exit( 1 )