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 ..”...)作为ARRAY ref,而在test.pl第46行,第80行使用“strict refs”时,测试时。第46行
我认为我的哈希值(%test
)是一个字符串,我无法将其拆分为数组。请告诉我如何将其转换为数组。我试过$test{$var_name} = [qw($var{value})];
它没有用。
答案 0 :(得分: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 :(得分:1)
这肯定是不对的:
$test{$_}->[$i]
因为$test{$_}
只能包含某种字符串。
如果你有一个字符串并且想要拆分成一个arrayref以便上面的工作,那就这样做:
$test{$var_name} = [split /\s+/, $var{value}];
我不知道代码应该完成什么,这意味着它可以运行,但我不知道它是否符合它的意图。奇怪的变量名称(如$test
和$var_name
并没有帮助我理解目的)。
答案 2 :(得分: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'
]
]
};