我正在尝试从Perl中的输入文件中读取值。 输入文件如下:
1-sampledata1 This is a sample test
and data for this continues
2-sampledata2 This is sample test 2
Data for this also is on second line
我想阅读上述数据,以便1-sampledata1
的数据进入@array1
,2-sampledata2
的数据进入@array2
,依此类推。
我将有大约50个这样的部分。比如50-sampledata50
。
编辑:名称不会一直是X-sampledataX。我就这样做了。所以名字不能循环。我想我必须手动输入
我到目前为止有以下(有效)。但我正在寻找一种更有效的方法来做到这一点..
foreach my $line(@body){
if ($line=~ /^1-sampledata1\s/){
$line=~ s/1-ENST0000//g;
$line=~ s/\s+//g;
push (@array1, $line);
#using splitarray because i want to store data as one character each
#for ex: i wana store 'This' as T H I S in different elements of array
@splitarray1= split ('',$line);
last if ($line=~ /2-sampledata2/);
}
}
foreach my $line(@body){
if ($line=~ /^2-sampledata2\s/){
$line=~ s/2-ENSBTAP0//g;
$line=~ s/\s+//g;
@splitarray2= split ('',$line);
last if ($line=~ /3-sampledata3/);
}
}
正如您所看到的,每个部分都有不同的数组,每个部分的循环不同。如果我采用方法,我到目前为止,我将最终得到50个for循环和50个数组。
还有另一种更好的方法吗?最后我想最终得到50个数组,但不想写50个循环。因为我将在程序中循环遍历50个数组,可能将它们存储在一个数组中?我是Perl的新手,所以它有点压倒......
答案 0 :(得分:4)
首先要注意的是,您正在尝试使用带有整数后缀的变量名:不要。每当您发现自己想要这样做时,请使用数组。其次,您只需要阅读一次,而不是多次查看文件内容。第三,Perl通常没有充分理由将字符串视为字符数组。
更新:此版本的代码使用前导空格来决定要执行的操作。我将离开之前的版本以供参考。
#!/usr/bin/perl
use strict;
use warnings;
my @data;
while ( my $line = <DATA> ) {
chomp $line;
if ( $line =~ s/^ +/ / ) {
push @{ $data[-1] }, split //, $line;
}
else {
push @data, [ split //, $line ];
}
}
use Data::Dumper;
print Dumper \@data;
__DATA__
1-sampledata1 This is a sample test
and data for this continues
2-sampledata2 This is sample test 2
Data for this also is on second line
以前的版本:
#!/usr/bin/perl
use strict;
use warnings;
my @data;
while ( my $line = <DATA> ) {
chomp $line;
$line =~ s/\s+/ /g;
if ( $line =~ /^[0-9]+-/ ) {
push @data, [ split //, $line ];
}
else {
push @{ $data[-1] }, split //, $line;
}
}
use Data::Dumper;
print Dumper \@data;
__DATA__
1-sampledata1 This is a sample test
and data for this continues
2-sampledata2 This is sample test 2
Data for this also is on second line
答案 1 :(得分:1)
#! /usr/bin/env perl
use strict;
use warnings;
my %data;
{
my( $key, $rest );
while( my $line = <> ){
unless( ($rest) = $line =~ /^ \s+(.*)/x ){
($key, $rest) = $line =~ /^(.*?)\s+(.*)/;
}
push @{ $data{$key} }, $rest;
}
}
答案 2 :(得分:1)
以下代码与@Brad Gilbert和@Sinan Unur的解决方案非常相似:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my (%arrays, $label);
while (my $line = <DATA>)
{
($label, $line) = ($1, $2) if $line =~ /^(\S+)(.*)/; # new data block
$line =~ s/^\s+//; # strip whitespaces from the begining
# append data for corresponding label
push @{$arrays{$label}}, split('', $line) if defined $label;
}
print $arrays{'1-sampledata1'}[2], "\n"; # 'i'
print join '-', @{$arrays{'2-sampledata2'}}; # 'T-h-i-s- -i-s- -s-a-m-p-l
print Dumper \%arrays;
__DATA__
1-sampledata1 This is a sample test
and data for this continues
2-sampledata2 This is sample test 2
Data for this also is on second line
i
T-h-i-s- -i-s- -s-a-m-p-l-e- -t-e-s-t- -2-D-a-t-a- -f-o-r- -t-h-i-s- -a-l-s-o- -i-s- -o-n- -s-e-c-o-n-d- -l-i-n-e-
$VAR1 = {
'2-sampledata2' => [
'T',
'h',
'i',
's',
' ',
'i',
's',
' ',
's',
'a',
'm',
'p',
'l',
'e',
' ',
't',
'e',
's',
't',
' ',
'2',
'D',
'a',
't',
'a',
' ',
'f',
'o',
'r',
' ',
't',
'h',
'i',
's',
' ',
'a',
'l',
's',
'o',
' ',
'i',
's',
' ',
'o',
'n',
' ',
's',
'e',
'c',
'o',
'n',
'd',
' ',
'l',
'i',
'n',
'e',
'
'
],
'1-sampledata1' => [
'T',
'h',
'i',
's',
' ',
'i',
's',
' ',
'a',
' ',
's',
'a',
'm',
'p',
'l',
'e',
' ',
't',
'e',
's',
't',
'a',
'n',
'd',
' ',
'd',
'a',
't',
'a',
' ',
'f',
'o',
'r',
' ',
't',
'h',
'i',
's',
' ',
'c',
'o',
'n',
't',
'i',
'n',
'u',
'e',
's',
'
'
]
};
答案 3 :(得分:0)
相反,您应该使用哈希映射到数组。
使用此正则表达式模式获取索引:
/^(\d+)-sampledata(\d+)/
然后,使用my %arrays
,执行:
push($arrays{$index}), $line;
然后,您可以使用$arrays{$index}
访问数组。