カレンダー

#($sec,$min,$hour,$mday,$month,$year,$wday,$stime) = localtime($times);
sub get_time(){
my ($t) = @_;
@a  =  localtime ( $t );
}

print $now = localtime;

@weekday = qw /Sun Mon Tue Wed Thu Fri Sat/;

print "<table border=1><tr>";
foreach(@weekday){
print "<td>$_<\/td>";
}
print "<\/tr>";


@b = &get_time(time);

$d = (@b[6] + 7) * -1;

for($i=0;$i<3;$i++){
print "<tr>";
for($j=0;$j<7;$j++){
@b = &get_time(time + $d * 24 * 3600);
$print_date = sprintf("%2d/%2d ",@b[4]+1,@b[3]);
print "<td>";
if($d == 0){
print "<b>";
print $print_date;
print "<\/b>";
}else{
print $print_date;
}
print "<\/d>";
$d++;
}
print "<\/tr>\n";
}

print "<\/tr><\/table>";





print(1+2)+3

print (1+2)+3;
を実行すると、3 と表示される。 最初はどうしてかわからなかったが、 以下のようにしてみるとわかる。
print (1+2);

print "\n";

print (1+2)+3;

print "\n";

$a=print(1+2);

print "\n";

$a=print(1+2);

print "\n";

print $a;

print "\n";

print (1+2)+3;

print "\n";
上記の出力結果は以下のようになる。
3
3
3
3
1
3
printという関数は引数を表示して結果を返す。
perl -e "print print \"hello\""
上記を実行すると
hello1
と表示される。helloの後ろにくっついている1は、print "hello" の実行結果である。 下記は「(1+2)の結果をprintし、その実行結果の値に3を足す」という意味になる。
print (1+2)+3
成功したらTRUE(1)なので1+3=4となるが、その値はprintされないので、 print(1+2) の結果の 3 のみが表示される。 もし (1+2)+3 という式の結果をprintしたいのであれば、以下のようにする必要がある。
print ((1+2)+3)

カレンダー

その日の前の週と翌週を含めた3週間を表示する。

@weekday = qw /Sun Mon Tue Wed Thu Fri Sat/;

print "<table border=1><tr>";

foreach(@weekday){
    print "$_<\/td>";
}

( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst )
=  localtime ( time );

$last = ($wday + 7) * -1;


$d=$last;
for($j=0;$j<21 24="" 3600="" d="" hour="" if="" isdst="" j="" localtime="" mday="" min="" mon="" print="" sec="" time="" tr="" wday="=0){" yday="" year="">";
    }
    print "

";
    printf("%2d/%2d ",$mon+1,$mday);
    print "<\/d>";

    if($wday==6){
        print "<\/tr>\n";
    }
    $d++;
}

print "<\/tr><\/table>";

ファイル列挙

重複チェックにはhashを使うと簡単らしい。
後でやってみる。

browse_directory("c:\\mydoc\\");

sub browse_directory{
local($dir)=@_;
local(*DIR,$file);

if(!opendir(DIR, $dir)){
return;
}

while ($file = readdir(DIR)) {
if(($file eq ".") || ($file eq "..")){
next;
}
if (-d "$dir\\$file") {
browse_directory("$dir\\$file");
}else{
$file_size = -s "$dir\\$file";
$file_size{"$dir\\$file"} = $file_size;
$file_name{"$dir\\$file"} = $file;
}
}
closedir(DIR);
}

foreach $fullpath (sort {$file_size{$b} <=> $file_size{$a}} keys %file_size)  {
print "$fullpath,$file_size{$fullpath},$file_name{$fullpath}\n";
}


指定したディレクトリ配下のファイルについて、フルパス、サイズ、ファイル名を取得してサイズの降順に並べる。

しかしこれには不具合がある。たまたま、フォルダ名が「○○表」というフォルダがあった。これがフォルダとしてではなく、ファイルとして認識されてしまったのだ。回避方法はあるようだがメンドクサイし意味がわからない。

shift-jisはダメだな。「ヤカン」が「ポット」とマッチするという冗談みたいなことが起きる。

while(<>){
if(/ポット/){
print;
print " matched\n";
}else{
print;
print " unmatched\n"
}
}


このスクリプトに「ヤカン」という文字列を含むファイルを読ませると、マッチする。




重複ファイルの整理

写真を整理していて、重複したファイルがたくさんあることに気付いた。最初はWindowsのエクスプローラでサイズ順にならべて、目で写真をみながら消していたのだが大量にありすぎるのでperlでなんとかしようと思った。まず、あるディレクトリ以下のjpgファイルとそのサイズを取得する。(thanks to internet)

recursive( '.' );
exit();

sub recursive
{
    my( $sBaseDir ) = @_;
    my( @FileLists, $sFileName );

    @FileLists = glob( $sBaseDir.'/*' );

    foreach $sFileName ( sort( @FileLists ) ){
        if ( -d $sFileName ){
            &recursive( $sFileName );
        } elsif ( -f $sFileName ){
            if ($sFileName =~ /\.jpg/){
                $filesize = -s $sFileName;
                print( "$filesize $sFileName \n" );
            }
        }
    }
}
あと、これをしないとフォルダやファイル名に空白が含まれたときにうまくいかない。
ppm install File-Glob-Windows
これでサイズとファイル名が取れる。今回はこれをExcelで開いてサイズでソートしてサイズが同じものだけを残した後、秀丸で置換を使ってhtmlにし、それを見て不要なファイルを残して、また秀丸の置換を使ってバッチファイルを作って消した。サイズが同じjpgでももちろん違うファイルの場合がある。ここは目視で確認せざるを得ない。だが、サイズが同じもののみを表示するhtmlファイルを作るまでなら一発で作れるだろう。

perlにはsortという関数があって1次元の配列なら簡単にソートできるが多次元になるとちょっと面倒だ。WEBにサンプルがいくつかあるのでそれを使えばいいのだが・・・と思ったところで気付いた。別に大きさ順にソートする必要はない。文字列としてソートしても重複なら検知できる。

my @found_files;

sub recursive
{
    my( $sBaseDir ) = @_;
    my( @FileLists, $sFileName );

    @FileLists = glob( $sBaseDir.'/*' );

    foreach $sFileName ( sort( @FileLists ) ){
        if ( -d $sFileName ){
            &recursive( $sFileName );
        } elsif ( -f $sFileName ){
            if ($sFileName =~ /\.jpg/){
                $filesize = -s $sFileName;
                $tmp = $filesize." ".$sFileName;
                push(@found_files,$tmp);
            }
        }
    }
}

recursive( '.' );

@found_files = sort(@found_files);

@saved_files=();
$saved_size=0;

foreach(@found_files){
    @a = split(/ /,$_);
    if(@a[0] ne $saved_size){
        if($#saved_files>0){
            foreach $b(@saved_files){
                $b =~ s/^/<img src="/g;
                $b =~ s/$/">/g;
                print "$b\n";
            }
            print "<br>";
        }
        @saved_files=();
        push(@saved_files,@a[1]);
        $saved_size=@a[0];
    }else{
        push(@saved_files,@a[1]);
    }
}
exit();

サイズだけでは結構同じものがある。ファイルサイズだけでなく、確か widthとheightも取れるはず。それも見よう。

use Image::Size;

my @found_files;

sub recursive
{
    my( $sBaseDir ) = @_;
    my( @FileLists, $sFileName );

    @FileLists = glob( $sBaseDir.'/*' );

    foreach $sFileName ( sort( @FileLists ) ){
        if ( -d $sFileName ){
            &recursive( $sFileName );
        } elsif ( -f $sFileName ){
            if ($sFileName =~ /\.jpg/){
                $filesize = -s $sFileName;
                $tmp = $filesize." ".$sFileName;
                push(@found_files,$tmp);
            }
        }
    }
}

recursive( '.' );

@found_files = sort(@found_files);

@saved_files=();
$saved_size=0;
$saved_width=0;
$saved_height=0;

foreach(@found_files){
    @a = split(/ /,$_);
    ($new_width,$new_height) = imgsize(@a[1]);
    if(@a[0] ne $saved_size){
        if($#saved_files>0){
            foreach $b(@saved_files){
                $c =$b;
                $b =~ s/^/<img src="/g;
                $b =~ s/$/">/g;
                print "$c$b\n";
            }
        print "<br>";
    }
    @saved_files=();
    push(@saved_files,@a[1]);
    $saved_size=@a[0];
    $saved_width=$new_width;
    $saved_height=$new_height;
    }else{
        if($new_width == $saved_width){
            push(@saved_files,@a[1]);
        }
    }
}
exit();


Image::Size モジュールを使って、widthもチェックした。これくらいできれば、個人の使用としては十分。