正規表現でmvできるスクリプト

mv で正規表現を使って,hoge001.jpg => hoge_001.jpg みたいな処理を一括してやりたいのだけど,後方参照ができないっぽいので,そんなスクリプトをかわいい PHP でサクっと書いてみた.sed とか find を組み合わせたらできると思うけど,このほうがかわいくて良い.

こんな感じで,対象のディレクトリに移動した後に,シェルのマッチングと組み合わせて使うことを想定している.

正規表現は色々とミスしたり,予想外のマッチが起きたりするので,確認機能をつけてある.

/target/dir% remv *.jpg "hoge(\d+)\.jpg" "hoge_\1.jpg"
Pattern RegExp: hoge(\d+)\.jpg
Destination RegExp: hoge_\1.jpg
Files:
fuga001.jpg: Not Match
fuga002.jpg: Not Match
hoge001.jpg => hoge_001.jpg
hoge002.jpg => hoge_002.jpg
hoge003.jpg => hoge_003.jpg
hoge004.jpg => hoge_004.jpg
hoge005.jpg => hoge_005.jpg
OK ? [y/N]:y
mv hoge001.jpg hoge_001.jpg: OK
mv hoge002.jpg hoge_002.jpg: OK
mv hoge003.jpg hoge_003.jpg: OK
mv hoge004.jpg hoge_004.jpg: OK
mv hoge005.jpg hoge_005.jpg: OK

イカスクリプト

#!/usr/bin/php
<?

	if($argc<4)
	{
		echo 'Error: few arguments: ', $argc, "\n";
		echo 'usage: ',$argv[0],' src0 src1 ... pattern_reg_exp dst_reg_exp', "\n";
		exit;
	}
	
	$num_srcs = $argc-3;
	$srcs = array();
	for($i=1; $i<$argc-2; ++$i)
		$srcs[] = $argv[$i];
	$pattern = '/'.$argv[$argc-2].'/i';
	$dst_re = $argv[$argc-1];
	
	echo 'Pattern RegExp: ', $pattern, "\n";
	echo 'Destination RegExp: ', $dst_re, "\n";
	
	echo "Files:\n";
	for($i=0; $i<$num_srcs; ++$i)
	{
		$dst = preg_replace($pattern, $dst_re, $srcs[$i]);
		if($dst==NULL)
			echo $srcs[$i], ': Error', "\n";
		else if($dst==$srcs[$i])
			echo $srcs[$i], ': Not Match', "\n";
		else
			echo $srcs[$i], ' => ', $dst, "\n";
	}
	
	echo 'OK ? [y/N]:';
	
	$answer = fgets(STDIN);
	
	if(substr(trim($answer),0,1)!="y")
		exit;
	
	for($i=0; $i<$num_srcs; ++$i)
	{
		$dst = preg_replace($pattern, $dst_re, $srcs[$i]);
		if($dst!=NULL && $dst!=$srcs[$i])
		{
			$r = rename($srcs[$i], $dst);
			$rs = $r ? 'OK' : 'Failed';
			echo 'mv ', $srcs[$i], ' ', $dst, ': ', $rs, "\n";
		}
	}

お友達が書いたPHP本を紹介.

パーフェクトPHP (PERFECT SERIES 3)

パーフェクトPHP (PERFECT SERIES 3)