2011-10-26 157 views
2

我正在寻找遍历这些数据结构(基本上是一个目录结构),我通过给定的路径。迭代通过数据数组/散列

的目标是要列出根/基本路径,然后列出所有的子path■如果它们存在和存在每个子path,列出从子路径file

我知道这可能需要循环HoH或AoH。有人能告诉我这样做的perl技术吗?谢谢。

基准面:/工作/工程/供稿

$VAR1 = { 
       'recursive' => 'no', 
       'version' => '0.20.202.1.1101050227', 
       'time' => '2011-10-26T00:20:18+0000', 
       'filter' => '.*', 
       'path' => '/work/eng/feeds', 
       'directory' => [ 
          { 
           'owner' => 'tst_act', 
           'group' => 'eng', 
           'permission' => 'drwxrwxr-x', 
           'path' => '/work/eng/feeds', 
           'accesstime' => '1970-01-01T00:00:00+0000', 
           'modified' => '2011-08-27T03:13:53+0000' 
          }, 
          { 
           'owner' => 'tst_act', 
           'group' => 'eng', 
           'permission' => 'drwxr-xr-x', 
           'path' => '/work/eng/feeds/customer_care', 
           'accesstime' => '1970-01-01T00:00:00+0000', 
           'modified' => '2011-10-25T23:54:17+0000' 
          } 
          ], 
       'exclude' => '' 
      }; 

下一等级:/工作/工程/供稿/ customer_care

$VAR1 = { 
      'recursive' => 'no', 
      'version' => '0.20.202.1.1101050227', 
      'time' => '2011-10-26T00:21:06+0000', 
      'filter' => '.*', 
      'path' => '/work/eng/feeds/customer_care', 
      'directory' => [ 
         { 
          'owner' => 'tst_act', 
          'group' => 'eng', 
          'permission' => 'drwxr-xr-x', 
          'path' => '/work/eng/feeds/customer_care', 
          'accesstime' => '1970-01-01T00:00:00+0000', 
          'modified' => '2011-10-25T23:54:17+0000' 
         }, 
         { 
          'owner' => 'tst_act', 
          'group' => 'eng', 
          'permission' => 'drwx------', 
          'path' => '/work/eng/feeds/customer_care/abc', 
          'accesstime' => '1970-01-01T00:00:00+0000', 
          'modified' => '2011-10-25T17:12:56+0000' 
         }, 
         { 
          'owner' => 'tst_act', 
          'group' => 'eng', 
          'permission' => 'drwx------', 
          'path' => '/work/eng/feeds/customer_care/def', 
          'accesstime' => '1970-01-01T00:00:00+0000', 
          'modified' => '2011-10-25T21:05:50+0000' 
         }, 
         { 
          'owner' => 'tst_act', 
          'group' => 'eng', 
          'permission' => 'drwx------', 
          'path' => '/work/eng/feeds/customer_care/test', 
          'accesstime' => '1970-01-01T00:00:00+0000', 
          'modified' => '2011-10-25T21:28:14+0000' 
         } 
         ], 
      'exclude' => '' 
     }; 

还有一个层次:/工作/工程/供稿/ customer_care /测试(这里是文件存在)

$VAR1 = { 
      'recursive' => 'no', 
      'version' => '0.20.202.1.1101050227', 
      'time' => '2011-10-26T00:30:02+0000', 
      'filter' => '.*', 
      'file' => { 
        'owner' => 'tst_act', 
        'replication' => '3', 
        'blocksize' => '134217728', 
        'permission' => '-rw-------', 
        'path' => '/work/eng/feeds/customer_care/test/q_data_20111023.dat', 
        'modified' => '2011-10-26T00:29:46+0000', 
        'size' => '379085', 
        'group' => 'eng', 
        'accesstime' => '2011-10-26T00:29:46+0000' 
        }, 
      'path' => '/work/eng/feeds/customer_care/test', 
      'directory' => { 
         'owner' => 'tst_act', 
         'group' => 'eng', 
         'permission' => 'drwx------', 
         'path' => '/work/eng/feeds/customer_care/test', 
         'accesstime' => '1970-01-01T00:00:00+0000', 
         'modified' => '2011-10-26T00:29:46+0000' 
         }, 
      'exclude' => '' 
     }; 
+0

你试过了什么?你遇到了哪些具体问题?你只需要知道'each','keys'和'values'的名字,或者阅读'perlreftut'? – derobert

+0

如果我可以捕获每个键和值,那将是一个好的开始。 – jdamae

回答

3

这里有一个首发:

sub list_path_files { 
    my ($data) = @_; 

    say $data->{path}; # get value from a hashref 

    my @directories; 
    # check whether it is a single value or an arrayref of values 
    if (ref $data->{directory} eq 'ARRAY') { 
     @directories = @{ $data->{directory} }; # dereference the arrayref to get an AoH 
    } else { 
     @directories = $data->{directory}; # just get the single value 
    } 

    for my $dir (@directories) { 
     next if $dir->{path} eq $data->{path}; 
     say $dir->{path}; 
    } 

    # I'll leave the rest for you to do 
} 

更新:

要遍历hashref,首先需要取消对它的引用,然后使用eachkeysvalues功能:

%hash = %$VAR1; # dereference 

while (my ($key, $value) = each %hash) {...} 

for my $key (keys %$VAR1) { 
    my $value = $VAR1->{$key}; 
} 

for my $value (values %$VAR1) {...} 

您还需要取消引用哈希如果它是嵌套结构,则为值:

if (ref $val eq '') { 
    # $val is just a scalar - don't need to deref 
} 
elsif (ref $val eq 'HASH') { 
    my %hash = %$val; 
} 
elsif (ref $val eq 'ARRAY') { 
    my @array = @$val; 
} 
+0

感谢首发。 – jdamae

0

由于数据中存在XML-esque时间戳,并且目录/文件结构是散列或散列数组,我会猜测您正在解析XML以构建初始散列?

如果您使用XML ::简单的XML阅读,

ForceArray => [ '目录', '文件']

将避免检查REF类型。

然后你就可以简化为这样的事情:

my %fs 

for my $item (values %your_giant_hash_with_fs_data) { 

    $fs{$_->{path}}='d' for (@{ $item->{directory} }); 
    $fs{$_->{path}}='f' for (@{ $item->{file} }); 

} 

my $search_path='/work/eng/feeds/customer_care/test'; 
my $search=qr/^$search_path/; 

for (sort keys %fs) { 

    print "$fs{$_} $_\n" if /$search/; 

} 

输出:

d /work/eng/feeds/customer_care/test 
f /work/eng/feeds/customer_care/test/q_data_20111023.dat 

,或者如果你不想创建一个临时结构

my $search_path='/work/eng/feeds/customer_care/test'; 
my $search=qr/^$search_path/; 

{ 
    my %seen; 
    for my $item (values %your_giant_hash_with_fs_data) { 
     for my $type (qw/directory file/) { 
      for (@{ $item->{$type} }) { 

       if ($_->{path}=~/$search/ and not $seen{$_->{path}}) { 

        printf("%-10s%s\n",$type,$_->{path}); 
        $seen{$_->{path}}=1; 

       } 

      } 
     } 
    } 
} 

这只因为你的每条路都是绝对的,绝对路径不能被复制

+0

谢谢,是的,我正在使用一个模块,它使用'XML :: Simple'来获取数据。我会开始测试这个。 – jdamae

+0

我仍然试图找出如何循环这一点。这里是我如何得到哈希数据:'我的$ listDetails = $ cmd-> ls(“/ work/eng/feeds/customer_care”);'。这是否取代我的哈希? from:对于我的$ item(值%your_giant_hash_with_fs_data)为我的$ item(值%listDetails)?再次感谢。 – jdamae

+0

啊。我认为所有的数据都存储在一个巨大的散列中,并且当它们成为依赖关系时,您并没有读取单个文件。 – John