[英]How to store data from hash in file and use it for another hash
I'm new in the Perl's world and I need help regarding the save data from a hash in a file and after that use it in another hash.我是 Perl 世界的新手,我需要有关从文件中的 hash 保存数据以及在另一个 hash 中使用它的帮助。
This is а short example of my code:这是我的代码的一个简短示例:
#!/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)
}
}
These are outputs from Dumper prints:这些是 Dumper 打印的输出:
$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'
}
}
};
The error is observed at second foreach loop:在第二个 foreach 循环中观察到错误:
foreach my $user (keys %{$data}) {
foreach my $job_id (keys %{$data->{$user}}) {
push (@old_array_id, $job_id)
}
}
output: Not a HASH reference at report.pl` output:不是报告中的 HASH 引用`
Actually, I'm not sure about the type of the retrieved data.实际上,我不确定检索到的数据的类型。 Could you please help with saving the data in the new hash?
您能帮忙将数据保存在新的 hash 中吗?
Best Regards, SK最好的问候, SK
Your $user_data
variable contains a hash reference.您的
$user_data
变量包含 hash 引用。 A hash reference is a scalar value. hash 引用是一个标量值。 I think you're getting confused by the synopsis of the documentation for Storable which contains examples like this:
我认为您对 Storable 文档的概要感到困惑,其中包含如下示例:
store \%table, 'file';
In the example above, %table
is a hash.在上面的示例中,
%table
是 hash。 You, therefore, need to take a reference to it in order to pass it to store()
.因此,您需要引用它才能将其传递给
store()
。 Because what you have in $user_data
is a hash reference, not a hash, you don't need to take its reference before passing it to store()
.因为您在
$user_data
中拥有的是 hash 引用,而不是 hash,所以您不需要在将其传递给store()
之前获取它的引用。 In fact, by taking its reference, you've added an extra level of indirection which breaks your code.事实上,通过引用它,您已经添加了一个额外的间接级别,这会破坏您的代码。
You say:你说:
Actually, I'm not sure about the type of the retrieved data.
实际上,我不确定检索到的数据的类型。
It's a reference to a hash reference.这是对 hash 参考的参考。 But your code is expecting just a hash reference.
但是您的代码只需要一个 hash 参考。
The simplest fix is to replace:最简单的解决方法是替换:
store (\$user_data, 'temp_jobs.txt') ... ;
with和
store ($user_data, 'temp_jobs.txt') ... ;
With that single-character deletion, your two data structures are the same and your code works as expected.通过删除单个字符,您的两个数据结构相同,并且您的代码按预期工作。
I like to use Yaml::XS for basic data structures, they're easier to look at later.我喜欢使用 Yaml::XS 作为基本的数据结构,它们以后更容易看。 I've included examples of YAML::XS and Storable
我已经包含了YAML::XS和Storable的示例
Hopfully this helps希望这有帮助
#!/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";
}
}
As an option you can save hash into JSON file.作为一个选项,您可以将 hash 保存到 JSON 文件中。 Following code demonstrates how desired result can be achieved.
以下代码演示了如何实现所需的结果。
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;
}
Output Output
--- 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'
];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.