[an error occurred while processing this directive] [an error occurred while processing this directive]

Love Perl?

Perlは「プログラム書こう」て動機のハードルが低いのがいいです。 ただ、掲示板くらいになるとそれなりの書き方を決めないと死にます。

複数行にわたる置換とか (正規表現)

"は\"みたいにエスケープしなくてもいい (しても実害ないみたいだけど)

複数行にわたるパターンを置換したい場合、 改行文字にもマッチさせたい場合、.だけではだめ。[\s\S]ってするのがお手軽。
edit.phpへのリンク及び、<form></form>にで囲まれた部分をすべて削除。 [s\S]*?で最短一致になっている。
$s="";
while(<>){
  $s .= $_;
}
$_=$s;
s/<a href="edit\.php.[^>]*?">([^<>]+?)<\/a>/$1/g; 
s/<form [\s\S]+?<\/form>/ /g;
print;

HTMLで、リストの順序(<ul>と</ul>の間)を入れ替え

while(<>){
    $before .= $_;
    last if (m/<ul/);
}

while(<>){
    last if (m/<\/ul/);
    $li = $_;
    while(<>){
        $li .= $_;
        last if(m/<\/li/);
    }
    push(@list_items, $li);
}
$after = $_;
$after .= $_ while(<>);

print $before;
print foreach(reverse(@list_items));
print $after;

フォルダの各ファイルについて…する

opendirを使うと、ディレクトリ内の各ファイルについて処理をする、ということができます。 リネームとかにも便利です。
  if (opendir(DIR, 'text/')){
    @utexts = readdir(DIR);
    closedir(DIR);
  }
こうすると、text/内のファイル一覧が@utextsという配列に入ります。
この結果はソートされていません。名前順でソートするには、
  @texts = sort { $a cmp $b} @utexts;
とするといいです。$aと$bは{}内だけで通用する変数で、いつも同じです。ソートを降順にしたければ、$aと$bを入れ替えます。ソートされた結果は@textsに代入されます。
これらのファイルについての処理は、foreachで書きましょう。 正規表現を使って、対象とするファイルを絞り込むのもよし。

  foreach $file (@texts){
    next if($file =~ /^([0-9]{2})\.txt$/); # 例えば、??.txtというファイル名にマッチしなければ捨てる
      open IN, "text/" . $file; #ファイル開く

一行スクリプト

perl -e "コマンド"
で、コマンドが実行されます。シェルで一行スクリプトを実行するのに便利。
awkとかsedだともっとスマートに書けそうだけど、perl覚えてるならそれ使っちゃった方が楽、かも。

faviconクローラー

aaa.comからzzz.comまでのアイコンを収集します。
タイムアウトは5秒です。
#!/usr/bin/perl

use LWP::Simple;

$thres = 3;

sub get_com($$){
    my ($str, $depth ) = @_;
    if($depth == $thres){
	print "Trying : $str ... ";
	my $page;
	eval {
	    local $SIG{ALRM} = sub { die "timeout" };
	    alarm 5;
	    $page = LWP::Simple::get("http://www.$str.com/favicon.ico");
	    alarm 0;
	};
	alarm 0;

	if($@) {
	    if($@ =~ /timeout/) {
		print "Timeout\n";
		next;
	    }
	}

	if( $page eq undef() ){
	    print "Undef\n";
	    next;
        }
	$_= substr($page, 0, 200);

	if(m/<html/i){
	    print "Html\n";
	    next;
	}
	open OUT, "<favicon/$str.ico";
	print OUT $page;
	close OUT;
	print "Wrote\n";
    } else {
	my $i;
	for($i = ord('a'); $i <= ord('z'); $i++){
	    get_com($str . chr($i), $depth + 1);
	}
    }
}

get_com("", 0);

画像ファイルをリスト表示

#!/usr/bin/perl

$dir = ".";

print  "Content-type:text/html\n\n<html><body>";
if (opendir(DIR, $dir)) {
  foreach(readdir(DIR)) { image($_) if(/.+\.(png|jpg|jpeg)$/i); }
  closedir(DIR);
}
print "</body></html>\n";

sub image { print "<a href='$_[0]'><img src='$_[0]' /></a><br />";}

超簡易スクリプト。$dirで指定されたディレクトリ内の画像ファイルをリスト表示します。
大きな画像を縮小表示したりとか、気の利いたことは何もしません。改造のたたき台にどうぞ。

フォルダをランダムな名前にリネーム

lsがある環境でしか使えません。(関数探すのが面倒だったので…) 1/1000000くらいの確率で同じ名前が何回か出そうですが…
@A = `ls -F`;

foreach (@A){
  chomp();
  next unless(m/.*\/$/);
  $new_fn = int(rand(1000000));
  $cmd = "mv $_ $new_fn";
#  print $cmd . "\n"; (いちおう出力確認)
  `$cmd`;
}

tips

プログラム書いてて経験したことのメモ。
[an error occurred while processing this directive]