Perlでコマンドプロンプトにサヨナラする(4)
Windows、LinuxのPerlのどちらでも、簡単な入出力の手段が分かりましたので、それを使ってプログラムを作ってみたいと思います。
今回は、入力文字列をファイルに保存して、それを簡単に検索できるような、簡単なデータベースもどきを作ってみたいと思います。
作戦
前回の記事で使用したwxPythonによるダイアログを使います。
入力した文字列は、データ保存用のテキストファイルに追加して、保存します。ファイルの内容は、最新の5行くらいを表示するようにします。
スラッシュを付けて入力することで検索、またはコマンドの入力と判断して、それぞれの処理を行います。
コマンドは、ヘルプ表示(/h)、削除(/d** (**:は番号))とします。
検索は、文字列を入力する(/検索文字)とそれを含んだ行を表示します。Perlのもつ文字列検索機能を使っているので、正規表現を渡すこともできます。
プログラム
EasyDataBase.pl (文字コードはUTF-8で保存すること)
#EasyDataBase (Programmed by CatmanP)
use strict;
use warnings;
use utf8;
use Wx;
my $datafile= "EasyDataBase.txt";
my $reexp= "";
my (@DBdata, $strdata, $strmsg, $save, $i);
while(1){
#ファイル読み込み
@DBdata= ();
if(-f $datafile){
open(A, "<:utf8", $datafile);
foreach(<A>){
chomp;
if($_ ne ""){
push(@DBdata, $_);
}
}
close(A);
}
#入力ウィンドウの作成
$i= 0;
$strdata= "";
if($reexp ne ""){
$strdata= "Search: $reexp\n";
}
foreach(@DBdata){
if($reexp ne ""){
if($_ =~ /$reexp/){ #検索結果
$strdata.= "$i: $_\n";
}
}elsif($#DBdata-5 < $i){ #DB表示(ラスト5行)
$strdata.= "$i: $_\n";
}
$i++;
}
$strdata =~ s/,/ /g;
$strmsg= Wx::GetTextFromUser($strdata, "EasyDataBase", " ");
#入力に対する処理
$reexp= "";
$save= 1;
if($strmsg eq ""){ #終了
last;
}
$strmsg =~ s/^ //;
$strmsg =~ s/ $//;
if($strmsg=~/\/(\w)(.*)/){ #コマンド
if($1 eq 'h'){ # ヘルプメッセージ
Wx::MessageBox(<<"EOT", "Help");
■使い方
文字列を入力するとデータベースに登録します
コンマ「,」で区切ると表示は空白に置き換わります
スラッシュ「/」で始めると下記コマンドの入力ができます
/h:Help
/[word]:Search word
/d[No.]:Delete
EOT
$save= 0;
}elsif($1 eq 'd'){ # 削除
splice(@DBdata, $2 -0, 1);
}else{ # 検索
$reexp= $1.$2;
$save= 0;
}
}else{
push(@DBdata, $strmsg); #入力文字列の追加
}
#ファイル書き出し
if($save==1){
open(A, ">:utf8", $datafile);
print(A join("\n", @DBdata));
close(A);
}
}
このプログラムは大きく4つのグループでできています。
「ファイル読み込み」「入力ウィンドウ作成」「入力文字列に対する処理」「ファイル保存」です。
ファイル読み込みでは、一行ずつ読み込みんで、行末の改行を削除しています。また、空行は飛ばすようにしています(空白文字の行ならば有効)。
ちなみに、改行削除にchomp;とだけ書いていますが、処理対象の文字列が省略されています。Perlには「省略の美」という考えがありまして、処理対象を省略できる書き方があります。ちゃんと書くとこんな感じ。
foreach $strtmp(<A>){
chomp($strtmp);
if($strtmp ne ""){
push(@DBdata, $strtmp);
}
}
次に$strdataに入力ボックスに表示する文字列を作成しています。
if文に「=~」を使っている行で、正規表現を使った文字列検索をしています。
どんな表示になったかは実行して確認してみてくださいね。
GetTextFromUserでは、初期値に半角スペース1文字を設定していて、文字を入力せずすぐEnterキーを押したとしても、プログラム終了しないようにしています。(文字無しの場合はプログラム終了に分岐します)
入力を取得したあとは、入力文字列を解析しています。
処理後のファイル保存は、$saveフラグが1のときに行うようにしています。
データは配列に保存してあるので、Perlならば保存は楽々です。
メモ
Perlの良さといったら、文字列の取扱いの良さ、とりわけ正規表現を手軽に試せるのは他の言語にはない魅力だと思います。
今回のプログラムでは、「=~」のある行は正規表現を使っていて、検索や置換を行っています。
このような文字処理の強みのため、ブログが登場する前あたり(2000年前半くらい)までのホームページでは、掲示板やチャットシステム、カウンターはPerlを使って作成していました。懐かしい…。
今回は、掲示板のプログラムを少し思い出しながら、でもできるだけシンプルにかつ簡単になるようにアレンジしながら作ってみました。
簡易データベースとして、辞書を作ってみても面白いかもしれません。
注意
データファイル読み書きに、ファイルロックの処理をしていないので、プログラムを複数立ち上げて同時に使うとデータが消えたりしますので、ご注意を。