第1回『「system」でぐーたらスクリプト』
まだフリー・ウェアで満足していますか?

 perlを使えば、
便利なスクリプトが簡単に作
れます。初めてperlに触って
から、一時間で、動くスクリ
プトを作れるようになる方法
をご紹介します。これで、今
日から、今から、誰でもperl
プログラマーです!


●今日からプログラマー!
 フリーウェアが沢山あるの
に、自分でツールを作る人が
います。だって、その方が、
手っとり早くて、自分の求め
ている通りのツールを手にで
きるからです。
 「でも、勉強に、一週間も
かかるなら、俺は、フリーウ
ェアでいいや……」。分かり
ました。では、あなたは、た
った今からperlプログラマー
です。
 もしも、windwosのMS-DOS
プロンプトから、dir、cd、
copy、pathなどのコマンドを
使え、|(パイプ)などの基
本的な記述方法がわかるなら、
たった今から、perlプログラ
マーになりましょう。(正規
表現も少しは、分かっていた
方が良いでしょう。)
 初めに断って置きますが、
私は、perlをまるで使えませ
ん。大きなスクリプトですと、
解読すらできないこともあり
ます。(^ ^;)
 しかし、必要は発明の母で
す。
------------------------  
1・必要だから使う。
2・動けばOK。
3・覚えることは最小限。
------------------------  
 こんな方針で、さっそく
行ってみましょう。はっきり
言いますが、perlは、超便利
です。こんな便利なもの、使
わないで、一体、どうします?


●入手先
 まだインストールもしてい
ない人、最新の入手先だけ書
いておきます。
・perlの入手先
http://computers.yahoo.co.jp/download/v
ector/win95/util/text/perl/
 拡張子plのファイルをダブ
ルクリックするとperlが立ち
上がるように、確実に設定し
ておきます。

・wcshの入手先
http://www.threeweb.ad.jp/~ishioka/
 wcshとは、MS-DOSプロンプ
トをコマンドラインから使う
のに便利な環境を提供してく
れる、ミニ・ツール群です。
perlから、今日のワンポイン
ト、system文によって、wcsh
のツールを呼び出して、楽を
してしまおうという意図です。
wcshのツール群に、pathを通
して置いてください。



●デジカメ写真の配布
 唐突ですが、デジカメ写真
を友達にあげる場合、どうし
ていますか? そのまま画像
だけをCD-Rに焼いて渡してい
るでしょうか? それとも、
susieやALBMといった画像ビュ
ーワも一緒に配布しています
か? 友達が、Macintoshユー
ザーだったら、どうします
か? パソコンを持っていな
い女の子に、印刷して配布す
る場合もあるでしょう。印刷
はなんのアプリでやりましょ
う?
 こうしたことを考えると、
たまった画像ファイルの配布
は、結構、面倒な難問です。
 今日は、画像ファイルの配
布と印刷を一気に簡単にする
ツールをperlで作ってみま
しょう。
--------------------------  
1・カレントフォルダにjpg
  やbmpなどの画像ファイル
  が沢山ある。
2・画像ファイルを8枚づつ、 
  htmlに貼り付ける。
  (ファイル名順)
3・「2」のhtmlをブラウザ
  で印刷した時、A4一枚で
  8枚印刷できる大きさに  
  縮小して貼り付けるよう
  にする。
4・「2」のhtmlの各縮小画
  像をクリックすると、
  100%の大きさで画像を見
  れる。
5・「2」のhtmlの「Next」
  をクリックすると、次の
  8枚のhtmlが開く。    
-------------------------  


 このようなhtmlを、perlで
自動生成します。
 沢山画像が入った各フォル
ダに、このようなhtmlがあれ
ば、win、Macユーザー関係な
く、ブラウザから画像ファイ
ルを閲覧できますし、印刷し
て配布するのも、ブラウザか
らできますから、特別なアプ
リケーションを使用する必要
がなくなります。
 勿論、大量の写真を配布す
る際、8枚/頁ではなく、例え 
ば、24枚/頁にするのも、良
い方法で、それには、これか
ら紹介するスクリプトの変数
を、たった三つ変えるだけで
済みますから、使い勝手は、
ばつぐんです。



●スクリプト
 リスト1のスクリプトを見
てください。たったこれだけ
のスクリプトで、複数の画像
を閲覧できるhtmlを自動生成
します。
 おまけに、perlの特徴であ
る、配列も、foreachも、サ
ブルーチンへの引数渡し、サ
ブルーチンから返り値参照も
使っていません。もっとも直
感的に分かりやすい命令だけ
で作りました。perlの初歩的
な文法を、「I/O」バックナ
ンバーや、ネットを参考にし
て少し勉強して見てください。

・変数
・ジャンプ・ループ
・条件分岐
・ファイル・画面への入出力
(・キーボードからの入力)

 ほとんどのプログラミング
言語は、上の使い方が分かれ
ば、大抵のことができるよう
になります。perlも同じです
ので、調べて下さい。特に
perlの場合は、ぐーたらに
使っても何とか動いたりしま
すから、必要なミニ・ツール
をいきなりつくりながら、覚
えて行くと良いでしょう。
 スクリプトには、少し変
わった命令にのみ、コメント
を付けておきました。
 使用方法は、こうです。
 画像ファイルのあるフォル
ダに、photo4-8jpg.plをコ   
ピーし、ダブルクリックで実
行します。生成された
photo4-8-1.htmlをダブルク  
リックすると、8枚づつ分割  
されたページを順に見ること
ができます。各写真をクリッ
クすると、大きく表示され、
Nextをクリックすることで、
ページをめくり、カレント
ディレクトリの総ての写真を
見ることができます。
 スクリプトの「$wide = 30  
0;$yoko = 2;$tate = 4;」の  
部分、$wide/$yoko/$tateの  
数値を、435/1/3に変更する  
と、3枚印刷、435/2/3で、  
6枚閲覧、200/4/6で、24枚  
閲覧用にスクリプトを変更す  
ることができます。      
 IEで写真を印刷したい時  
は、ファイル→ページ設定の  
印刷ヘッダ(デフォルトは   
「&w &u &d&b&p/&P ページ」) 
を、空欄にし、「余白」欄を  
全て5ミリ程度に設定します。 
プリンタによっては、スクリ  
プトの「$wide =」の値を小さ 
く調整し、写真が用紙に収ま  
るようにして下さい。     



●system文とループ
 system文は、perlから
MS-DOSプロンプトのコマンド
を実行します。

│MS-DOSプロンプト
│dir /b /a:a > list.txt
│
│perlスクリプト
│system(` dir /b /a:a > list.txt`);

 これは、どちらも、カレン
トディレクトリのファイルの
み(ディレクトリを無視して
アーカイブのみ)をlist.txt
と言う中間ファイルに出力し
ます。
 grepは、ファイルの中から、
特定の文字列のみを抽出する
コマンド(wcsh収録)で、
sortは、ファイルを文字列順
に並べ替えるコマンド(同上
収録)です。ですから、

│dir /b /a:a | grep "\.[jJbBgG][pPmMiI]
[gGpPfF]$"  | sort > list.txt

 は、カレントディレクトリ
のファイルから、拡張子jpg 
JPG bmp BMP gif GIFのみを
抽出し、list.txtと言うファ
イルに出力します。(本当は、
拡張子がjMfなんいうファイ
ルにもマッチしてしまいます
が、今回は、目をつぶること
にします。)
 system文で注意すべきなの
は、

│system(` dir /b /a:a | grep "\\\.jpg\$"  > list.txt`);

 のように、\と$を\でエス
ケープする必要があることで
す。
 $を除外して説明すると、
"."は、正規表現の特殊文字
なので、MS-DOSプロンプトか
ら、grepで".jpg"のある行の
みを抽出したい時は、"\.jpg"
と指定します。しかし、system
文に"\.jpg"を渡すと、MS-DOS
に渡される際に、grepに、
".jpg"が渡されてしまい、結
果、grepコマンドは、"\.jpg"
でなく、".jpg"を検索してし
まい、任意の一文字+jpgを
抽出することになってしまう
ため、"\\\.jpg"を渡します。
 更に、特に、文字列の末尾
を示す"$"を指定したい時、
"\$"の前の"\"を忘れると、
system文が、MS-DOSにうまく
パラメータを渡せなくなり、
エラーになります。
 perlには、foreachをはじ
め、ループに種類があります
が、あまり見かけない、

│open (infile, "< hoge.txt");
│while( <infile> ) {
│(処理行);
│}

 の形式が、system文→中間
ファイル出力という方法と組
合わせた時、もっとも重宝す
るループ形式です。
 動作としては、オープンし
たhoge.txtの各行を一行づつ、
$_と言う変数に取り込みつつ、
「}」までの間でループしま
す。hoge.txtに読み込む行が
なくなったら、ループを抜け
ます。
 尚、今回system文で実現し
た動作は、配列を使い、perl
だけで記述できます。中間
ファイルも使用する必要はあ
りません。その方が、スクリ
プトとしては、ずっとスマー
トです。しかし、こんな方法
で、perlを学んだ初日から、
そこそこ便利なスクリプトを
作れると言うことに驚いた方
は、どうか、今から早速、
perlを触ってみて下さい。


#photo4-8jpg.pl
#フォルダにある画像ファイルをA4 2×4の印刷用htmlに格納する。
#jperl用スクリプト。sjisで保存。
#CGIではなく、MS-DOSプロンプトから起動し、複数のHTMLを作成するスクリプト

#変数初期値
$wide = 300;$yoko = 2;$tate = 4;$jpglist = "jpglist.txt";

#↑スクリプトの各行は、「;」で終わりますが、このように、複数行を
#一行にまとめることができます。

$pagefr = $yoko * $tate;$tit = "photo${pagefr}-";$nowpage = 1;
system(` dir /b /a:a | grep "\\\.[jJbBgG][pPmMiI][gGpPfF]\$"  | sort > $jpglist`);
#↑egrepを持っていれば、egrep "(\.jpg\$|JPG\$|bmp\$|BMP\$|gif\$|GIF\$)"
#のように記述します。

#ループ
$nowyoko = 1;$nowfr = 1;open (infile, "< $jpglist");

while( <infile> ) {
	$nowfr == 1 && &head;
	#↑変数$nowfrが1と等しい場合、サブルーチンheadが実行されます。
	#このように、「&&」の左辺が成立する場合、右辺が実行されます。
	#if文よりすっきりしたスクリプトを書けます。
	$nowyoko == 1 && &gyost;
	&body;
	$nowyoko++;  #$nowyoko = $nowyoko + 1と同じ意味;
	$nowfr++;
	$nowyoko > $yoko && &gyoend;
	$nowfr > $pagefr && &pageend;
}

$nowyoko != 1 && &gyoend;
$nowfr != 1 && &pageend;

#サブルーチン
sub head {
	$nextpage = $nowpage + 1;
	open ( outfile, ">${tit}${nowpage}.html");
	print outfile <<EOF
<HTML><HEAD><!--雀の往来--><TITLE>${tit}${nowpage}.html</TITLE></HEAD>
<BODY BGCOLOR=#FFFFFF link=#FFFFFF alink=#000000 vlink=#FFFFFF>
<a href=${tit}${nextpage}.html><FONT COLOR="#000000">
page ${nowpage}→Next</FONT></a><TABLE BORDER=0>
EOF
}
#↑「<<EOF」から、「EOF」の行までの文字列を、出力ファイルに吐き出します。

sub pageend {&end;close ( outfile);$nowfr = 1;$nowpage++;}

sub end {
print outfile <<EOF
</TABLE><a href=${tit}${nextpage}.html><FONT COLOR="#000000">
page ${nowpage}→Next</FONT></a></BODY></HTML>
EOF
}

sub gyost {print outfile "<TR>";}

sub gyoend {$nowyoko = 1;print outfile "</TR>";}

sub body {
print outfile <<EOF
<TD VALIGN = TOP>$_<BR><A HREF="./$_"><IMG SRC="$_" WIDTH=${wide}></A></TD>
EOF
}