penguin/utils

my env utils

php/regRename.php

raw ยท 6988 bytes

<?php

error_reporting ( E_ALL^E_NOTICE ) ;

//----------- Usage -----------

if ( !$argv[1] ) 
	die ( "Usage: php {$argv[0]} [options] [-d directory] [-p patterns] [-s \"first match\" \"second\" ...] [...args]\n
  -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

" ) ;

//------- End Usage -----------


class ArgvParser
{
	//parseOptions utilitiese by tgckpg
	static function PARSE ( $argStream, $handler ) {
		//Chop first useless argument -- argv[0]
		array_shift ( $argStream ) ;
		//Initiate ArrayObject for iterator
		$arrayobject = new ArrayObject ( $argStream ) ;
		//Initiate iterator for iteration
		$iterator = $arrayobject->getIterator();

		//If options is set first
		if( $iterator->valid() && preg_match ( '/^-\w$/', $iterator->current() ) ) {
			//iterate through whole argument stream
			for (	; $iterator->valid(); $iterator->next() ) {
				//Check if reached next option
				if( preg_match ( '/^-\w$/', $opts = $iterator->current() ) ) {
					//Get current options
					$currOpt = $opts;
					//echo "$currOpt\n";
					//Test if next stream is an option
					for ( $iterator->next(); $iterator->valid(); $iterator->next() ) {
						if ( preg_match ( '/^-\w$/', $opts = $iterator->current() ) ) {
							//echo "$currOpt $opts\n";
							$handler($currOpt);
							$currOpt = $opts;
						} else break;
						//var_dump($iterator->valid());
					}
				}//End if
				//echo "$currOpt $opts\n";
				$handler($currOpt, $opts);
				//A temporary fix for infinite loop
				if(!$iterator->valid())
					break;
			}// End for
		//If option is not set first.
		} else {
			//Try other approach.
		}// End if
	}
}


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 --------
}





$rrgr = new RegRename();
ArgvParser::PARSE ( $argv, array($rrgr, 'setOption') ) ;
$rrgr->begin();

?>