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

How to store data from hash in file and use it for another hash

我是 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}->{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)
   }
}

这些是 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'
                                                }
                               }
            };

在第二个 foreach 循环中观察到错误:

foreach my $user (keys %{$data}) {
   foreach my $job_id (keys %{$data->{$user}}) {
      push (@old_array_id, $job_id)
   }
}

输出:在 report.pl`

处不是 HASH 引用

实际上,我不确定检索到的数据的类型。你能帮忙把数据保存在新的哈希中吗?

此致, SK

基本的数据结构我喜欢用Yaml::XS,方便以后看。我已经包含了 YAML::XS and Storable

的示例

希望这对您有所帮助

#!/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_data 变量包含哈希引用。散列引用是标量值。我认为您对 documentation for Storable 的概要感到困惑,其中包含如下示例:

store \%table, 'file';

在上面的例子中,%table 是一个散列。因此,您需要引用它才能将其传递给 store()。因为您在 $user_data 中拥有的是哈希引用,而不是哈希,所以在将它传递给 store() 之前不需要获取它的引用。事实上,通过引用它,您已经添加了一个额外的间接级别,这会破坏您的代码。

你说:

Actually, I'm not sure about the type of the retrieved data.

它是对哈希引用的引用。但是您的代码只需要一个哈希引用。

最简单的修复方法是替换:

store ($user_data, 'temp_jobs.txt') ... ;

store ($user_data, 'temp_jobs.txt') ... ;

通过 single-character 删除,您的两个数据结构相同,您的代码按预期工作。

作为一个选项,您可以将哈希保存到 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;
}

输出

--- 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'
        ];