使用perl的外部文本文件中的哈希数据结构

时间:2014-06-24 21:27:30

标签: perl data-structures perl-module

我是perl的初学者。下面的脚本解析存储在哈希中的值,如果字符串不存在则抛出错误。

#!usr/bin/perl

use feature qw/say/;

$hash = {
  'testing' => {
    'link' => "http://www.espn.com",
    'bandwidth' => "100",
    'r' => "2",
  },
};

die "'testing' not found!" unless($hash->{'testing'});

say $hash->{'testing'}->{'link'} // (die "'link' not found!");
say $hash->{'testing'}->{'bandwidth'} // (die "'bandwidth not found!");

以上程序的输出是

http://www.espn.com
100

现在不是在脚本中指定值,而是希望将哈希值存储在txt文件中,例如hash.txt。如何在脚本中调用该文本文件。

以下值在文件hash.txt中指定。我不知道如何在我的脚本中调用此文件。有什么建议吗?

'testing' => {
        'link' => "http://www.espn.com",
        'bandwidth' => "100",
        'r' => "2",
      },

3 个答案:

答案 0 :(得分:2)

核心模块Storable可用于无痛地序列化数据结构:

use Storable;
store \%table, 'file';
$hashref = retrieve('file');

Storable的许多函数抛出异常(即它们die)而不是在失败时返回undef,因此如果需要恢复,我建议使用Try::Tiny模块 - 它更容易而不是试图解决手动正确保留$ @的麻烦。

也可以使用Data::Dumper编写明文文件,然后将其全部读入并eval重新创建数据结构。有点复杂,但生成的存储文件比Storable创建的人类更易读。要重读它,你可以自己实现它:

use autodie; # For the convenience of this example;
             # makes all open()s, close()s, etc die
             # without needing to type `or die "$!\n";' repeatedly

my $serialized_hash = do {
    open my $fh, '<', 'hash.txt';
    local $/; # Undefine $/ for this scope...
    <$fh>;    # so <> slurps up the entire file
};

或使用File :: Slurp(也在核心,效率很高)

use File::Slurp;
my $serialized_hash = read_file('hash.txt');

然后eval

my %hash;
eval $data;

此外,如果您正在检查哈希中是否存在密钥而不是其值是否已定义,请使用exists函数,该函数与delete协同工作。

来源:

perldoc Storable

perldoc -f exists

答案 1 :(得分:0)

尝试类似这样的事情,假设哈希中所需的值存储在名为in.txt的文件中:

http://www.espn.com 100 2
www.example.com 20  1
www.no_bandwith.com     1

(请注意,第3个条目缺少带宽值)

use strict;
use warnings;

open my $in, '<', 'in.text' or die $!;

my %data;
my $line_count = 0;
while (<$in>){
    chomp;
    $line_count++;
    my @split = split(/\t/);
    if ($split[0] eq ''){
        print "missing link for line $line_count\n";
        next;
    }
    if ($split[1] eq ''){
        print "missing bandwith for line $line_count\n";
        next;
    }
    $data{$line_count} = [ $split[0], $split[1], $split[2] ];
}

for my $line (keys %data){
    my ($link, $bwidth, $r) = @{$data{$line}};
    print "$link, $bwidth, $r\n";
}

输出:

missing bandwith for line 3
http://www.espn.com, 100, 2
www.example.com, 20, 1

答案 2 :(得分:0)

您希望在CORE&#34;中学习基础知识和&#34;做这样的事情的技巧,并掌握Perl的语言(在你的情况下存储/检索数据结构,Storable是一个不错的选择),所以坚持使用其他一些经过尝试的真实反应这个帖子。您最终希望查看使用JSON,YAML等的各种模块以及其他序列化数据的方法。

但是,只是为了激起你的兴趣,这里举例说明你可以用新的perl和几个CPAN模块做些什么:

#!/usr/bin/env perl

use 5.10.0;
use DDP;
use IO::All;

my $testing_hash < io './testing.hash' ;
my $hash = { eval $testing_hash } ;

p $hash ;

say $hash->{'testing'}{'link'} // (die "'link' not found!");

输出:

\ {
    testing   {
        bandwidth   100,
        link        "http://www.espn.com",
        r           2
    }
}
http://www.espn.com

use中的CPAN模块: