简体   繁体   English

如何将 hash 的数据存储在文件中并将其用于另一个 hash

[英]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::XSStorable的示例

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM