- 締切済み
ハッシュのハッシュでデータベース
ハッシュのハッシュになっているデータをファイルに書き出しておき、必要なときにまたプログラムから使いたいと思っています。検索スピードを問題にするほどの量ではありませんし、チェックのために時々は自分で読みたいので、どちらかといえばテキストデータのほうが便利かなあと考えていますが、特に決めてはおりません。 何か便利な方法がありましたら、教えて頂けないでしょうか。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
Perlのデータ構造をそのままテキストデータに変換できるモジュールがいくつか有りますので、それらを利用すると簡単です。 個人的にMLDBMモジュールが好みですが、ほとんどの環境で利用できる Data::Dumperモジュールが良いでしょう。 #!perl use Data::Dumper; my $hash_ref = { Perl => {version => '5.6.0', url => 'http://www.perl.com/'}, Python => {version => '1.5', url => 'http://www.python.org/'} }; open FILE, "> data.file" or die $!; print FILE Dumper $hash_ref; __END__ このようなスクリプトで、$hash_refの構造を文字列としてファイルに保存できます。この文字列を書き出したファイルを読み込み、eval()で評価すれば再度プログラムで利用することができるようになります。 また、前記のMLDBMモジュールは同様に hash の hashやhashのlistなどを、直接dbmに格納するためのジュールです。flat fileではなくdbmに格納するため可読性は落ちますが、高速に入出力を行うことができます。
補足見ました。 確認なんですが、この「$domain」というのは、もしかして変数名でしょうか?(それとも単に例としてこういう名前にしただけ?) もし変数名ならば、ダブルクォート(”)でかこってしまったら、それは文字列になってしまいますので、変数$domainの内容を参照することはできないですよ。 また、下のほうで「\%info」という使い方をされているようですが、これも変数として扱ってもらえません。なぜなら、¥の次に%を書くと、「連想配列変数の接頭文字」としての「%」の効能が消えてしまうからです。 見たところCの多重階層の構造体のようなことをやろうとなさっているようですが、Perlにはポインタという考え方がないので(似て非なるものならあるんですが)、その辺を気をつけなければいけません。
別に再利用できますよ。 今回のは「とは」とか「日にデート」とかいう冗談が入ってましたが、通常区切り文字はカンマです。 ですので、 %hash = ("みちこ", 4, "さちえ", 5, "ゆうこ", 6); @keys = keys(%hash); open(OUT, ">datescadule.txt"); foreach $key ( @keys ) { print OUT "$key,$hash{$key}¥n"; } close(OUT); というようにカンマによってデータを区切れば、読み出すときは、 open(IN, "<datescadule.txt"); @datas = <IN>; close(IN); #chompは配列に対して行い、引数を取った方がよい $n=chomp(@datas); foreach $data ( @datas ) { ($key, $value) = split(/,/, $data); $hash{$key} = $value; } とこうすれば、元通りハッシュにデータが戻ります。 これが「カンマ区切りテキスト」つまりCSV形式というわけです。
補足
すみません、説明不足のようで。 ハッシュのハッシュ、あるいは配列のハッシュだと、CSV等として保存・参照・追記をするにはどうするのでしょうか。 想定している構造体?は、下のようなものです。 %info= ( "ドメイン名" => "$domain", "ネットワークサービス名" => "$networkservice", "組織名" => "$soshikimei", "住所" => "$juusho", ); %database=("$domain" => \%info); (このドメインのデータはあるか? あるならそのネットワークサービス名は何か? ネットワークサービス名が無いなら組織名は何か? というような使い道を考えております。)
ハッシュのさらにハッシュ、というのがどういう仕様になっているのかよく分かりませんが、基本的に下記のソースを参考にしてもらえばいいと思います。 %hash = ("みちこ", 4, "さちえ", 5, "ゆうこ", 6); @keys = keys(%hash); open(OUT, ">datescadule.txt"); foreach $key ( @keys ) { print OUT "$key とは $hash{$key} 日にデート\n"; } close(OUT); これで、ハッシュ変数%hashの内容をすべてテキストファイルに書きだします。 どういう形式でファイルに収めるかは、”(ダブルクォート)で囲まれた部分を自分なりに変更することで決めてください。
補足
ご解答ありがとうございます。 いろいろ考えてみたのですが、配列のハッシュでもできるような気がしてきました。 さて、書いて頂いた方法ですと、ファイルにしたデータベースをハッシュとして再利用することができないように思えるのですが、パターンマッチなどを利用して取り出すということでしょうか?
Perl ならばテキストかCSV形式(テキストのカンマ区切り形式)にしておいた方が圧倒的に便利です。 なぜならPerlは、「文字列の操作が得意」という理由でインターネットに普及した言語だからで、バイナリデータの扱いをそれほど得意としていないからです。
補足
有難うございます。 ハッシュのデータから、そのテキストやCSV形式に書き出す為の、便利な方法を御教示いただけないでしょうか。
補足
ありがとうございます。おそくなりました。 例に挙げたプログラムは、私の環境では一応動作したのですが。 少なくとも邪道だということですね。 さて、皆様の御助言を参考にさせて頂いて、下のように致しました。 $domainをインデックスがわりにしてデータの有無をチェックし、あれば読み込み、無ければデータを作って追記するーという流れです。 ただ、たとえば参照する度にカウンタを上げていくなど、データの書き換え機能をつける方法がわかりませんので、それが現在の課題です。 #------------------------ sub check_file{ #----------------- open(IN, "domaindata.txt"); while ($_ = <IN>) { chop; @data_from_file = split(/\t/, $_); if($data_from_file[0] eq $inputed_domain){ ($domain, $shubetsu, $networkservice, $soshikimei, $zip, $juusho, $teikyousha, $daihyou, $fukudaihyou) = @data_from_file; return 1; break; } } close(IN); return 0; #-------------- } #------------------------ #------------------------ sub write_to_file{ #----------------- @data_to_file = ($domain, $shubetsu, $networkservice, $soshikimei, $zip, $juusho, $teikyousha, $daihyou, $fukudaihyou); open(OUT, ">>domaindata.txt"); print OUT join("\t", @data_to_file)."\n"; close(OUT); #-------------- } #------------------------