第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 }