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

初期ファイル.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 .."...) は ARRAY ref として使用できませんが、test.pl の 46 行目、80 行目で "strict refs" が使用されています。

私が持っていた hash( %test) 値は文字列であり、配列として分割できないと思います。配列に変換する方法を教えてください。やってみ$test{$var_name} = [qw($var{value})];ましたがダメでした。

4

3 に答える 3

1

これは確かに正しくありません:

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

$test{$_}ある種の文字列しか含めることができないためです。

文字列があり、上記が機能するように配列参照に分割したい場合は、次のようにします。

$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 に答える