プロが教える店舗&オフィスのセキュリティ対策術

先日、カレンダー日記のperlによるスクリプト構造について質問させていただいたのですが、
今回の質問は、その処理をする上で知っておくべき処理は何なのかを教えていただきたく、質問させて頂きました。

perlの参考書は多いですが、以下の処理をズバリ書いてくれている書籍はないので、以下の処理を実現するなら、このような処理を書いている本を買えばいいというような助言をお願いします。書籍名でも助かります。

以下、処理の内容

カレンダー日記の構造は、
日付けをクリックすると、例えば本日なら、20030427という値を変数に格納して、
nikki.cgiファイルに飛ばすようにしようと思っています。

nikki.cgiファイルは、受け取った変数を記憶して、
nikki.datファイルからその、20030427で始まる一行を探すようにします。
nikki.datファイルの中身は、一つの改行コードが出てくるまでを一日分とします。
たとえば、
20030427,4月27日(土),22:14,今日も快晴だった
というような一行が、一日分です。

こうした一行が何行も書かれているnikki.datファイルの中からクリックされた日付けを見つけ出して、返すという仕組みです。

データベース的な処理?のようなので、どういった知識をつければ、より今後の勉強に役に立つか、そういったことを知りたくなったので、アドバイスを頂きたいと思います。

書店で見たperlの本のサンプルは、たいてい、
掲示板、チャット、アクセスカウンタ、全文検索、などばかりで、
カレンダー日記というのはなかったもので、果たしてどういう処理の勉強から取り組めばいいのか、そこに立ち返ろうと思っています。

全文検索あたりがnikki.datファイルの中から一行を選び出すという意味で、
似ているかなと思ったのでタイトルにしてみましたが、実際のところ、どうでしょうか。
宜しくお願いします。

A 回答 (6件)

すみません。

#5の修整です。

open (FILE,"<nikki.dat") or die;

while (<FILE>){
chomp;
$a = 0;
($date,$time,$hizuke,$content) = split (/,/);
while ($db{$date}{$time}[$a]){ $a++; }
$db{$date}{$time}[$a] = "$hizuke,$content";
}
close FILE;

$c = 0;
foreach $key (sort keys %{$db{$request}}){
$a = 0;
while ($db{$request}{$key}[$a]){
($hizuke,$content) = split (/,/, $db{$request}{$key}[$a]);
print "$hizuke $content\n";
$a++;
}
$c++;
}
print "none data\n" if ($c == 0);

#5だと、同じ時間のデータが二つ以上あった場合、
一つしか表示されません。
    • good
    • 0
この回答へのお礼

ありがとうございます。

ご丁寧にスクリプトまで組んでくださいまして、本当にありがとうございました。

じっくり解析させていただき、
自分のコーディングに活かさせていただきます。

ありがとうございました!

お礼日時:2003/04/28 01:32

データベースを使うのが一番良い方法だと思いますが、


レンタルサーバなどでは使えなかったりします。
バージョン5以降のPERLならデータ構造をサポートして
いるので、

例えば、nikki.datがあるとして、
----------------------
030424,0830,4/24-8:30,data1
030425,1230,4/25-12:30,data2
030426,0920,4/26-9:20,data3
030426,1030,4/26-10:30,data4
030426,1040,4/26-10:40,data5
030427,1500,4/27-15:00,data6
----------------------
上記のデータから4/26分のデータを取り出には、

$request = '030426';

open (FILE,"<nikki.dat") or die;

while (<FILE>){
chomp;
($date,$time,$hizuke,$content) = split (/,/);
$db{$date}{$time} = "$hizuke,$content";
}
close FILE;

$c = 0;
foreach $key (sort keys %{$db{$request}}){
($hizuke,$content) = split (/,/, $db{$request}{$key});
print "$hizuke $content\n";
$c++;
}
print "none data\n" if ($c == 0);

のような方法はどうでしょうか。
ただし、この方法だと、データ数が多くなると効率が
悪くなるので、nikki_dataフォルダを作って、その中
に一ヶ月分ずつ(例:0302.dat,0303.dat,0304.dat)の
ファイルを作ってやる方がいいと思います。
    • good
    • 0
この回答へのお礼

たしかにデータがおおくなると大変そうですが、
ご指摘の通り、月ごとにいれていこうと思います。

ありがとうございました。

お礼日時:2003/04/28 01:33

Perl のみの処理でしたら No.2 さんの回答が最もスタンダードな方法だと思いますよ。


先日の split 関数書き方違ってましたね、すみません。
最近はあんまり Perl 使わないので・・・

DBM は、dbmopen と dbmclose を使うだけですよ。
その中でデータを連想配列として扱えます。
ただ、使える文字数に制限があった気がします。

結論から申しますとテキストにデータを書き込んでいくのでしたら、それを読み込んで処理する以外に方法はないと思いますが・・・
    • good
    • 0
この回答へのお礼

ありがとうございます。

dbmについての本を見かけたことがあるので、
そちらも考慮して考えていこうと思います。

それにしても今日は本当に一日どっぷりと
スクリプトとにらめっこしていました。

非常に面白いですが、大変です。

ありがとうございました。

お礼日時:2003/04/28 01:34

全文検索とは違うと思いますよ。


今回の場合、特定のカラムからレコードを取り出すという考えでいくと SQL を使うと楽でしょう。
例えば、テーブル名が「diary」で日付のカラム名が「date」だと仮定すると、

select * from diary from date = '20030427';

で、該当するレコードが全て返されます。
フリーのデータベースで有名なのは PostgreSQL と MySQL ですね。
ただし、これを導入する技術と SQL や日常の管理方法も覚えないといけません。
また、Perl から扱う為には DBI などのモジュールも必要です。
上記 SQL 文は最も簡単なものですが、データベースも、テーブルの正規化やインデックスのはり方、そして SQL の発行方法が違うだけで処理速度が大幅に変わります。
Perl はテキスト処理が得意な言語なので、データサイズが小さければデータベースを導入するまでの必要はないと思います。
日付がユニークな値でしたら DBM とか使ってみたらどうでしょうか?
簡易データベースみたいなもので、考え方は連想配列と同じです。
    • good
    • 0
この回答へのお礼

ありがとうございます。

SQLですか、聞いたことはあるんですが、
Perlもままならないのに、さらに他言語になってしまうとちょっと頭が痛いですが、
やはり日記検索になるとこうした処理が必要になっちゃうんですよね。

Perlをまずはもっと鍛えたいので、Perlのみで考えると、Perlの処理で一番似ているのは、
読み込み、表示の意味では掲示板に近いと思いますが、
ネックとなるのは、やはり特定の日付けの検索ということになりますよね。

DBMというのは、書店でちらりと見たりしましたが、
難しいんでしょうか。連想配列の意味ならなんとかわかるので、まだいけるかなと思ったりします。

ですが、あえてPerlにこだわるとしてアドバイスをいただけないでしょうか。
書店にて似ている処理について書かれている書籍を本日買い求めようと思っています。

お礼日時:2003/04/27 10:51

データが以下のように','(カンマ)区切りであった場合,


20030427,4月27日(土),22:14,今日も快晴だった

データファイルを一行ずつ読み込んで,','で分割して配列に放り込みます。で,検索対象と$dateが一致していたら,何らかの処理をし,一致していなかったら,次へ,・・・でファイルを全て読み込むまで繰り返し。という処理になると思います。

$date='20030427';

open FILE,'nikki.dat';
while (<FILE>) {
  chomp($_);
  @data=split(/,/,$_);
  if ($data[0] eq $date) {
    //該当する
    処理
  } else {
    //該当しない
    next;
  }
}
close FILE;

のようなかんじで。
    • good
    • 0
この回答へのお礼

ありがとうございます。

シンプルにまとまっていて、理解しやすかったです。
じっくりとくみ上げようと思います。

ありがとうございました。

お礼日時:2003/04/28 01:35

@thatday = grep(/^20030427\,$/,@dat);


かな?

全文検索などの知識はまったくありませんので、
もっと効率良い、または安全な方法があるのかもしれません。
    • good
    • 0
この回答へのお礼

ありがとうございます。

勉強いたします。

お礼日時:2003/04/28 01:35

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!