diff --git a/php/astropenguin/botanical/RegRename.php b/php/astropenguin/botanical/RegRename.php deleted file mode 100644 index fbac369..0000000 --- a/php/astropenguin/botanical/RegRename.php +++ /dev/null @@ -1,225 +0,0 @@ -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 -------- -} diff --git a/php/regRename.php b/php/regRename.php deleted file mode 100644 index b402b78..0000000 --- a/php/regRename.php +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env php - Directories to look over - -p Define RegEx patterns - -r Rename file recursively - -s Strings that will replace the matches - - Optional: - -e Exclude defined pattern - -l 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(); - - diff --git a/python/reg-rename.py b/python/reg-rename.py new file mode 100644 index 0000000..033db0c --- /dev/null +++ b/python/reg-rename.py @@ -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 )