2013-06-04 51 views
0

data.txt中改變從字符串的哈希值,以陣列

Name:xyz 
ID:1 
Value: 1 2 3 4 5 6 7 8 9 ... 
ID:2 
Value: 9 8 7 6 5 4 3 2 1.. 
ID:3 
Value: 90 89 88.... 
Name:abc 
ID:11 
value:... 

INTIAL FILE.TXT

## Header 
.. 
data 
data 
data 
.. 

最終預期file.txt的

## Header xyz_1,xyz_2,xyz_3,abc_11,... 
.. 
data 1 9 90 
data 2 8 89 
data 3 7 88 
data 4 6 
.. 

電流輸出file.txt的

## Header xyz_1,xyz_2,xyz_3,abc_11,... 
... 
data, 1 2 3 4 5 6 7 8 9 ..,9 8 7 6 5 4 3 2 1 ..,90 89 88 
data 
data 
... 

代碼

#!/usr/local/bin/perl 
use diagnostics; 
use strict; 
use warnings; 

use Tie::File; 

my @name_id; 
my %test; 

#local $/ = ''; 

open my $fh, '<', 'data.txt' or die "failed: $!"; 
my %var; 
while (<$fh>) { 
    chomp; 
    if (m/^([A-Z:]+):\s*(.*)/) { 
    $var{$1} = $2; 
    if (exists($var{Name}) && exists($var{ID}) && exists($var{value}) && $1 eq 'value') { 
     my $var_name = "$var{Name}_$var{ID}"; 
     push @name_id, $var_name; 
     $test{$var_name} = $var{value}; 
    } 
    } 
} 

# print join "\n\t", @test{@name_id}; 
my $match = "## Header"; 
tie my @lines, 'Tie::File', 'file.txt' or die "failed : $!"; 
for my $line (@lines) { 
    if ($line =~ /^($match.*)/) { 
    $line = $1 . "," . join ',', @name_id; 
    } 
} 
untie @lines; 

my $match = "data"; 
tie my @lines, 'Tie::File', 'file.txt' or die "failed : $!"; 
my $i = 0; 
for my $line (@lines) { 
    if ($line =~ /^($match.*)/) { 
    $line = $1 . "," . join(',', map { $test{$_}->[$i] } @name_id); 
    $i++; 
    } 
} 
untie @lines; 

有一個問題,這條線$line = $1 . "," . join (',', map { $test{$_}->[$i]} @name_id);它拋出

不能使用串的誤差( 「1 2 3 4 5 6 7 8 9 ..」 ... )作爲數組引用而「嚴格參」在使用中test.pl線46,線80在test.pl線46

我認爲散列(%test)值我是一個字符串,我可以將它分解爲一個數組。請讓我知道如何將其轉換爲數組。我試圖做$test{$var_name} = [qw($var{value})];它沒有工作。

+0

爲什麼你會混'$ i'和'在同一代碼共同$ 1'?爲什麼:(。請改名爲 – BLaZuRE

回答

3

你可能有興趣在這個重構你的代碼,似乎你想要做什麼。

#!/usr/local/bin/perl 
use strict; 
use warnings; 

use Tie::File; 

open my $fh, '<', 'data.txt' or die "failed: $!"; 

my @name_id; 
my %test; 
my %var; 

while (<$fh>) { 
    chomp; 
    if (my ($key, $val) = /^(\w+):\s*(.*)/) { 
    $var{$key} = $val; 
    if ($key eq 'value') { 
     my $var_name = "$var{Name}_$var{ID}"; 
     push @name_id, $var_name; 
     $test{$var_name} = [ split ' ', $var{value} ]; 
    } 
    } 
} 

tie my @lines, 'Tie::File', 'file.txt' or die "failed : $!"; 
my $count = 0; 
for my $line (@lines) { 
    if ($line =~ /^## Header/) { 
    $line .= ' ' . join ',', @name_id; 
    } 
    elsif ($line =~ /^data/) { 
    $line .= ' ' . join ' ', map { $test{$_}[$count] // '' } @name_id; 
    $count++; 
    } 
} 
untie @lines; 

輸出file.txt

## Header xyz_1,xyz_2 ,xyz_3 
data 1 9 90 
data 2 8 89 
data 3 7 88 
data 4 6 
1

這肯定是不對的:

$test{$_}->[$i] 

因爲$test{$_}只能包含某種形式的字符串。

如果你有一個字符串,並要分割成一個數組引用因此上述作品,這樣做:

$test{$var_name} = [split /\s+/, $var{value}]; 

我不知道是什麼的代碼應該完成的,這意味着它可以運行,但我不知道它是否做到了。奇數變量名稱(如$test$var_name並沒有幫助我理解目的)。

+0

它的工作原理。這就是我需要的,儘管它抱怨'$ line = $ 1。「,」。join(',',map {$ test {$ _} - > [$ i]} @name_id);'在test4.pl第47行,<$fh>行 141(#1) – user2441289

+0

可能你可以重新打開一個新的問題,順便提一下,我仍然認爲你應該清理變量名稱。 – mzedeler

0

我不太確定我是否跟着你的代碼,但我想我會發布如何轉置數字(除非你的代碼已經這樣做:-))。

#!/usr/bin/perl 
use strict; 
use warnings; 

my (%data, $name); 
while (<DATA>) { 
    if (/^Name:(.+)/) { 
     $name = $1 
    } 
    elsif (/^Value/) { 
     # transpose 
     my $r = 0; 
     push @{ $data{$name}[$r++] }, $_ for /\d+/g; 
    } 
} 

use Data::Dumper; print Dumper \%data; 

__DATA__ 
Name:xyz 
ID:1 
Value: 1 2 3 4 5 6 7 8 9 
ID:2 
Value: 9 8 7 6 5 4 3 2 1 
ID:3 
Value: 90 89 88 87 86 85 84 83 82 
Name:abc 
ID:11 

轉儲的結果是:

$VAR1 = { 
      'xyz' => [ 
        [ 
         '1', 
         '9', 
         '90' 
        ], 
        [ 
         '2', 
         '8', 
         '89' 
        ], 
        [ 
         '3', 
         '7', 
         '88' 
        ], 
        [ 
         '4', 
         '6', 
         '87' 
        ], 
        [ 
         '5', 
         '5', 
         '86' 
        ], 
        [ 
         '6', 
         '4', 
         '85' 
        ], 
        [ 
         '7', 
         '3', 
         '84' 
        ], 
        [ 
         '8', 
         '2', 
         '83' 
        ], 
        [ 
         '9', 
         '1', 
         '82' 
        ] 
        ] 
     };