Perl 如何将散列中的数据存储在文件中并将其用于另一个散列
我是Perl领域的新手,我需要有关将散列数据保存到文件中,然后在另一个散列中使用数据的帮助 这是我的代码的一个简短示例:Perl 如何将散列中的数据存储在文件中并将其用于另一个散列,perl,hash,storable,Perl,Hash,Storable,我是Perl领域的新手,我需要有关将散列数据保存到文件中,然后在另一个散列中使用数据的帮助 这是我的代码的一个简短示例: #!/usr/local/bin/perl use FileHandle; use File::Copy; use Data::Dumper qw(Dumper); use Storable; use warnings; use strict; my $user_data; $user_data->{test_user}->{1256489043}->{
#!/usr/local/bin/perl
use FileHandle;
use File::Copy;
use Data::Dumper qw(Dumper);
use Storable;
use warnings;
use strict;
my $user_data;
$user_data->{test_user}->{1256489043}->{STATUS} = "RUN";
$user_data->{test_user}->{1256489043}->{MEM} = "51591";
$user_data->{test_user}->{1256489043}->{RUN_TIME} = "41410";
$user_data->{test_user}->{1256489043}->{PROJ_NAME} = "unkown";
$user_data->{test_user}->{1256489043}->{GROUP} = "default";
$user_data->{test_user}->{1256489043}->{DATE} = "Aug 17 05:23";
$user_data->{test_user_2}->{528562752}->{STATUS} = "RUN";
$user_data->{test_user_2}->{528562752}->{MEM} = "591";
$user_data->{test_user_2}->{528562752}->{RUN_TIME} = "46410";
$user_data->{test_user_2}->{528562752}->{PROJ_NAME} = "unkown";
$user_data->{test_user_2}->{528562752}->{GROUP} = "default";
$user_data->{test_user_2}->{528562752}->{DATE} = "Aug 17 05:23";
store (\$user_data, 'temp_jobs.txt') or die "can't store data to $!";
my $data = retrieve('temp_jobs.txt');
print "Hash 1\n";
print Dumper \$user_data;
print "Hash2\n";
print Dumper \$data;
my @new_array_id;
foreach my $user (keys %{$user_data}) {
foreach my $job_id (keys %{$user_data->{$user}}) {
push (@new_array_id, $job_id)
}
}
my @old_array_id;
foreach my $user (keys %{$data}) {
foreach my $job_id (keys %{$data->{$user}}) {
push (@old_array_id, $job_id)
}
}
这些是转储打印的输出:
$VAR1 = \{
'test_user_2' => {
'528562752' => {
'GROUP' => 'default',
'PROJ_NAME' => 'unkown',
'DATE' => 'Aug 17 05:23',
'STATUS' => 'RUN',
'RUN_TIME' => '46410',
'MEM' => '591'
}
},
'test_user' => {
'1256489043' => {
'GROUP' => 'default',
'PROJ_NAME' => 'unkown',
'DATE' => 'Aug 17 05:23',
'STATUS' => 'RUN',
'RUN_TIME' => '41410',
'MEM' => '51591'
}
}
};
$VAR1 = \\{
'test_user' => {
'1256489043' => {
'GROUP' => 'default',
'PROJ_NAME' => 'unkown',
'DATE' => 'Aug 17 05:23',
'STATUS' => 'RUN',
'RUN_TIME' => '41410',
'MEM' => '51591'
}
},
'test_user_2' => {
'528562752' => {
'GROUP' => 'default',
'PROJ_NAME' => 'unkown',
'DATE' => 'Aug 17 05:23',
'STATUS' => 'RUN',
'RUN_TIME' => '46410',
'MEM' => '591'
}
}
};
在第二个foreach循环中观察到错误:
foreach my $user (keys %{$data}) {
foreach my $job_id (keys %{$data->{$user}}) {
push (@old_array_id, $job_id)
}
}
输出:report.pl处不是哈希引用`
实际上,我不确定检索到的数据的类型。你能帮我把数据保存在新的散列中吗
致以最良好的祝愿,
SK我喜欢将Yaml::XS用于基本数据结构,它们更易于以后查看。我已经包括了和的例子 希望这能有所帮助
#!/usr/bin/env perl
use strict;
use warnings;
use Storable;
use YAML::XS;
use Data::Dumper;
my $struct = {
'test_user_2' => {
'528562752' => {
'GROUP' => 'default',
'PROJ_NAME' => 'unkown',
'DATE' => 'Aug 17 05:23',
'STATUS' => 'RUN',
'RUN_TIME' => '46410',
'MEM' => '591'
}
},
'test_user' => {
'1256489043' => {
'GROUP' => 'default',
'PROJ_NAME' => 'unkown',
'DATE' => 'Aug 17 05:23',
'STATUS' => 'RUN',
'RUN_TIME' => '41410',
'MEM' => '51591'
}
}
};
#print Dumper($struct);
#print Dump($struct);
YAML::XS::DumpFile("store.yaml", $struct);
my $read_yml = YAML::XS::LoadFile("store.yaml");
print "yaml out\n";
print Dumper($read_yml);
store $struct, 'store.perl_str';
my $hashref = retrieve('store.perl_str');
print "store out\n";
print Dumper($hashref);
print "looping data\n";
for my $user_key ( sort keys %{ $hashref } )
{
my $user = $hashref->{$user_key};
for my $id_key ( sort keys %{ $user } )
{
print "$user_key - $id_key\n";
print " " . $user->{$id_key}{"DATE"} . "\n";
print " " . $user->{$id_key}{"STATUS"} . "\n";
}
}
$user\u数据
变量包含哈希引用。散列引用是一个标量值。我想你会被这本书的大纲搞糊涂了,其中包括这样的例子:
store \%table, 'file';
在上面的示例中,%table
是一个散列。因此,您需要对其进行引用,以便将其传递到store()
。由于$user\u data
中包含的是散列引用,而不是散列,因此在将其传递到存储()之前,不需要获取其引用。事实上,通过引用它,您已经添加了一个额外的间接级别,这会破坏您的代码
你说:
实际上,我不确定检索到的数据的类型
它是对散列引用的引用。但您的代码只需要一个哈希引用
最简单的修复方法是替换:
store (\$user_data, 'temp_jobs.txt') ... ;
与
通过单字符删除,您的两个数据结构是相同的,并且您的代码按预期工作。作为一个选项,您可以将哈希保存到JSON文件中。下面的代码演示了如何实现期望的结果
use strict;
use warnings;
use feature 'say';
use JSON;
use Data::Dumper;
my $fname = 'datafile.json';
my $user_data;
$user_data->{test_user}{1256489043}{STATUS} = "RUN";
$user_data->{test_user}{1256489043}{MEM} = "51591";
$user_data->{test_user}{1256489043}{RUN_TIME} = "41410";
$user_data->{test_user}{1256489043}{PROJ_NAME} = "unkown";
$user_data->{test_user}{1256489043}{GROUP} = "default";
$user_data->{test_user}{1256489043}{DATE} = "Aug 17 05:23";
$user_data->{test_user_2}{528562752}{STATUS} = "RUN";
$user_data->{test_user_2}{528562752}{MEM} = "591";
$user_data->{test_user_2}{528562752}{RUN_TIME} = "46410";
$user_data->{test_user_2}{528562752}{PROJ_NAME} = "unkown";
$user_data->{test_user_2}{528562752}{GROUP} = "default";
$user_data->{test_user_2}{528562752}{DATE} = "Aug 17 05:23";
my $json = to_json($user_data);
write_json($fname,$json);
my $data = read_json($fname);
say '--- Read from file -----------------';
say Dumper($data);
say '-' x 45;
say Dumper( jobs_array($user_data) );
say '-' x 45;
say Dumper( jobs_array($data) );
sub jobs_array {
my $data = shift;
my @array;
for my $user ( keys %{$data} ) {
for my $job_id ( keys %{$data->{$user}} ) {
push @array, $job_id;
}
}
return \@array;
}
sub write_json {
my $fname = shift;
my $data = shift;
open my $fh, '>', $fname
or die "Couldn't open $fname";
say $fh $data;
close $fh;
}
sub read_json {
my $fname = shift;
open my $fh, '<', $fname
or "Couldn't open $fname";
my $data = do{ local $/; <$fh> };
close $fh;
my $href = from_json($data);
return $href;
}
您修复了OP的问题(store$struct
而不是store\$struct
),但没有指出实际的修复方法。如果OP继续尝试序列化\$struct
并反序列化为$struct
@dave,那么切换到另一种序列化格式也不会有什么不同。你完全正确。我错过了。但是,我确实觉得,如果代码可以简化,那么问题就会消失。将数据存储在yaml(或json或其他格式)中确实会使直接查看文件变得容易得多,这在某些情况下无疑是人们想要做到的。我认为您的示例令人困惑,因为它执行了两次序列化和反序列化$read_yml
实际上已经反序列化了$hashref
,并且从未使用过它YAML::XS::LoadFile()
已根据以下说明为您提供了要查找的$hashref
:。要获得更清晰的代码,您应该只使用1种序列化方法。提示:store(\$user\u data,
应该是store($user\u data,
。一个人想把一个标量传递给转储程序
,所以他使用\@a
和\%h
来处理数组和散列,但标量已经是标量了,所以使用\$s
只会毫无意义地使事情复杂化。Woops,我不知道这是问题的根本原因。我同意JSON(或YAML)这是一种更好的序列化格式。但是更改格式并不会改变根本问题。如果OP序列化对哈希引用的引用并反序列化它,期望得到哈希引用,那么无论选择哪种格式,他们都会遇到完全相同的问题。
use strict;
use warnings;
use feature 'say';
use JSON;
use Data::Dumper;
my $fname = 'datafile.json';
my $user_data;
$user_data->{test_user}{1256489043}{STATUS} = "RUN";
$user_data->{test_user}{1256489043}{MEM} = "51591";
$user_data->{test_user}{1256489043}{RUN_TIME} = "41410";
$user_data->{test_user}{1256489043}{PROJ_NAME} = "unkown";
$user_data->{test_user}{1256489043}{GROUP} = "default";
$user_data->{test_user}{1256489043}{DATE} = "Aug 17 05:23";
$user_data->{test_user_2}{528562752}{STATUS} = "RUN";
$user_data->{test_user_2}{528562752}{MEM} = "591";
$user_data->{test_user_2}{528562752}{RUN_TIME} = "46410";
$user_data->{test_user_2}{528562752}{PROJ_NAME} = "unkown";
$user_data->{test_user_2}{528562752}{GROUP} = "default";
$user_data->{test_user_2}{528562752}{DATE} = "Aug 17 05:23";
my $json = to_json($user_data);
write_json($fname,$json);
my $data = read_json($fname);
say '--- Read from file -----------------';
say Dumper($data);
say '-' x 45;
say Dumper( jobs_array($user_data) );
say '-' x 45;
say Dumper( jobs_array($data) );
sub jobs_array {
my $data = shift;
my @array;
for my $user ( keys %{$data} ) {
for my $job_id ( keys %{$data->{$user}} ) {
push @array, $job_id;
}
}
return \@array;
}
sub write_json {
my $fname = shift;
my $data = shift;
open my $fh, '>', $fname
or die "Couldn't open $fname";
say $fh $data;
close $fh;
}
sub read_json {
my $fname = shift;
open my $fh, '<', $fname
or "Couldn't open $fname";
my $data = do{ local $/; <$fh> };
close $fh;
my $href = from_json($data);
return $href;
}
--- Read from file -----------------
$VAR1 = {
'test_user' => {
'1256489043' => {
'RUN_TIME' => '41410',
'MEM' => '51591',
'PROJ_NAME' => 'unkown',
'STATUS' => 'RUN',
'GROUP' => 'default',
'DATE' => 'Aug 17 05:23'
}
},
'test_user_2' => {
'528562752' => {
'GROUP' => 'default',
'STATUS' => 'RUN',
'MEM' => '591',
'PROJ_NAME' => 'unkown',
'DATE' => 'Aug 17 05:23',
'RUN_TIME' => '46410'
}
}
};
---------------------------------------------
$VAR1 = [
'1256489043',
'528562752'
];
---------------------------------------------
$VAR1 = [
'1256489043',
'528562752'
];