何だか使いまわしで似たディレクトリ構成が複数できちゃった場合。 仕様が違うんだから少しずつ違うのは当然なんですが共通の物も多い。 どれが最新というバージョンアップでなくて微妙な仕様違いという複数バージョンですから、 バージョンに枝が生えてるのでどれかのバグが取れても他のが修正漏れで残ったりしてイカンです。 なるべく同じファイルで両方で動くように処理を書き加えて同じファイルが両方にあるようにするんだけど、仕様が違うんだからいつも同じというわけではない。自分だけが編集してるわけでないし。 なーんて場合に、複数ディレクトリを指定すると同じ名前のファイル同士を比較しまくってバージョンを分類します。 ●いまのところ表示幅を計算する部分の関数がバイト数を数えているだけなので「『全角』は2バイト」というshift_jisやeucのような文字コードならこのまま動きますがUTF-8のように2倍幅の文字が3バイトになったりする場合には縦がずれます。表示幅計算部分が関数として分けてあるので日本語を含むファイル名を使う場合にはここに処理を書き加えればいいでしょう。 ●linuxなどのunix系で動かすように出来てますがwindowsならcygwinとかcoLinuxとかでこのまま動くことでしょう。unix系でもmacの場合はcompare関数のcmpのパスを変えるなどの必要があるかも。 ●ファイル比較はunixに昔からある/usr/bin/cmpというコマンドを単に呼び出していますが表示幅のケースと同じくファイル比較部分も関数として分けてあるので必要に応じてここを書き換えればこのコマンドを呼ばなくなります。 ●昔から欲しかったんだけどどこにも見つかんないからついに作った。 ●コンソールコマンドですが小さい文字で画面いっぱいの大コンソールにするとかして使うのが吉。 ●タダでコピーして使ってかまいませんし改造や転用やguiの付加等も自由ですが末尾にある僕のidのついたアフィリエイトリンクは何らかの形で有効な購入行動に結びつくように残してください。こういうのは何ライセンスって言うんだ? |
使い方 |
fileversions dir ...
unix系のコマンドラインでディレクトリ名を並べて指定します。
|
fileversions |
|
fileversions |
|
#!/usr/bin/perl # fileversions -- compare files in multi directories -- 2008/11/16-20 by i16 @arg=@ARGV; $condensed=$header=0; sub badcommandline { print STDERR "usage: fileversions (-ch) dir ...\n\n-c: condensed\n-h: header\n"; exit -1; } while(substr($arg[0],0,1) eq "-") { $p=substr($arg[0],1); while((length($p) > 0) && (($c=substr($p,0,1)) ne "-")) { if($c eq "c") { $condensed=1;} elsif($c eq "h") { $header=1;} else { badcommandline();} $p=substr($p,1); } shift @arg; } @dir=@arg; $dirs=$#dir+1; $DEBUG=0; if(!$dirs) { badcommandline();} sub compare { my($f1,$f2)=@_; return 1 if -s $f1 != -s $f2; return system("/usr/bin/cmp","-s","$f1","$f2") / 256; } sub ls { my($d)=@_; my($i,$f,@w); if(substr($d,-1)=="/") { $d=substr($d,0,-1);} opendir(D,$d); for($i=0;defined($f=readdir(D));) { if(($f ne ".") && ($f ne "..")) { $w[$i++]=$f; } } closedir(D); return sort @w; } sub printwidth { return length($_[0]);} for($i=0;$i<$dirs;$i++) { if(substr($dir[$i],-1) ne "/") { $dir[$i].="/";} @wkwk=&ls($dir[$i]); for($maxw=$count=0;$f=shift @wkwk;$count++) { $wk=&printwidth($f); $maxw=$wk if $maxw<$wk; $ls[$i][$count]=$f; } $lss[$i]=$count; $maxwidth[$i]=$maxw; } for($i=0;$i<$dirs;$i++) { $ix[$i]=0;} sub fchar { my($f); return " " if $name eq ""; $f=$dir[$i].$name; return "/" if -d $f; return "." if -f $f; return "?"; } sub alldone { my($i); for($i=0;$i<$dirs;$i++) { return 0 if $ix[$i]<$lss[$i];} return 1; } sub pw { my($w,$s)=@_; printf("%-*s",$w,substr($s,0,$w));} sub pi { my($s)=@_; pw($maxwidth[$i]+2,$s);} if($header) { if($condensed) { $t=0; do { for($i=1;$i<$dirs&substr($dir[0],-$t-1) eq substr($dir[$i],-$t-1);$i++) { ; } if($dirs&&$i>=$dirs) {$t++;} } while($dirs&&$i>=$dirs); for($i=0;$i<$dirs;$i++) { printf("%*d:%s\n",$i*2+1,$i,substr($dir[$i],0,-$t)); } for($i=0;$i<$dirs;$i++) { if($i) { if($i%10) { print " ";} else {print ($i/10)%10;} } print $i%10; } print " x ----+----1----+----2----+----3\n"; } else { for($i=0;$i<$dirs;$i++) { print " " if $i; pi($dir[$i]); } print"\n\n"; } } while(!&alldone()) { for($name="",$i=0;$i<$dirs;$i++) { if($ix[$i]<$lss[$i]) { $wk=$ls[$i][$ix[$i]]; if(($name eq "") || (($name cmp $wk) > 0)) { $name=$wk; } } } $curver="A"; for($i=0;$i<$dirs;$i++) { if($name ne $ls[$i][$ix[$i]]) { if($condensed) { print "-";} else { pi("-");} } else { $chr=&fchar(); if($chr ne ".") { if($condensed) { print $chr;} else { pi($name.$chr);} } else { for($j=0;$j<$i;$j++) { if($name eq $ls[$j][$ix[$j]-1]) { if(!compare($dir[$j].$name,$dir[$i].$name)) { $chr=$ver[$j]; last; } } } if($j>=$i) { $chr=$curver; $curver=chr((ord($curver)-ord('A')+1)%26+ord('A')); } $ver[$i]=$chr; if($condensed) { print $chr;} else { pi($name.";".$chr);} } $ix[$i]++; } print " "; } print chr((ord($curver)-ord('A')-1)%26+ord('A')); if($condensed) {print" ".$name;} print "\n"; } # donations ... you may use this program at no charge, # but if you are about to buy a book or dvd or pcs or lcds or plasmavisions or others, # please go to an amazon through following links. thank you (^_^)/ -- i16 # # jp http://www.amazon.co.jp/exec/obidos/redirect-home/i16jp-22 # de http://www.amazon.de/exec/obidos/redirect-home/i16jp0f-21 # fr http://www.amazon.fr/exec/obidos/redirect-home/i16jp0a-21 # ca http://www.amazon.ca/exec/obidos/redirect-home/i16jp0b-20 # uk http://www.amazon.co.uk/exec/obidos/redirect-home/i16jp-21 # us http://www.amazon.com/exec/obidos/redirect-home/i16jp-20 # #end of fileversions -- i16 |
fileversions |