0

数据.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:...

初始文件.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 
..

当前输出文件.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 行

我认为我拥有的 hash( %test) 值是一个字符串,我不能将它拆分为一个数组。请让我知道如何将其转换为数组。我试过这样做$test{$var_name} = [qw($var{value})];没有用。

4

3 回答 3

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 
于 2013-06-05T02:10:10.287 回答
1

这肯定是不对的:

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

因为$test{$_}只能包含某种字符串。

如果您有一个字符串并且想要拆分为一个 arrayref 以便上述工作,请执行以下操作:

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

我不知道代码应该完成什么,这意味着它可以运行,但我不知道它是否完成了它的意图。奇怪的变量名称(喜欢$test$var_name没有帮助我理解目的)。

于 2013-06-04T23:01:21.827 回答
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'
                     ]
                   ]
        };
于 2013-06-04T23:37:22.907 回答