2011-10-26 211 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