我尝试使用foreach循环外部的索引键值从数据中打印列。
my @col;
foreach(<DATA>){
@x = split(' ',$_);
@xz = ($x[0],$x[1],$x[2]) ;
#print "$x[0]\n"; This is working but i'm not expect this.
push(@col,@xz);
}
print "$col[0]\n";
__DATA__
7 2 3
3 2 8
6 7 2
我希望输出
7 3 6
我该怎么做?
答案 0 :(得分:3)
始终使用use strict;
和use warnings;
!!
您有几个问题:
push( @col, @xz );
在这种情况下,您在<{1}}数组中丢失您的信息。在这个循环之后,你得到一个如下所示的单个数组:
@xz
所以,当你打印时:
@col = ( 7, 2, 3, 3, 2, 8, 6, 7, 2);
你得到第0个元素:7。
我们可以使用reference:
来保留数据的结构print "$col[0]\n";
在这里,您看到我已包含Data::Dumper以打印出#! /usr/bin/env perl
#
use strict; # Lets you know when you misspell variable names
use warnings; # Warns of issues (using undefined variables
use feature qw(say);
use Data::Dumper;
my @columns;
for my $data ( <DATA> ) {
my @data_list = split /\s+/, $data;
push @columns, \@data_list;
}
say Dumper \@columns;
__DATA__
7 2 3
3 2 8
6 7 2
的结构:
@columns
如您所见,$VAR1 = [
[
'7',
'2',
'3'
],
[
'3',
'2',
'8'
],
[
'6',
'7',
'2'
]
];
数组中的每个条目现在都是另一个数组。但是,打印出@columns
数组引用不会打印出您想要的内容。相反,它将打印第0个数组引用:7,2,3,而不是每个数组引用的第0个元素:7,3,6。
为此,我们需要一个子例程,它将通过$columns[0]
并打印出每个数组的第0个条目。在这里,我正在创建一个名为@columns
的子程序,它将获取传递的数组的传递索引:
fetch_index
子例程只遍历我存储在数组中的每个数组引用,并从该数组引用中获取#! /usr/bin/env perl
#
use strict; # Lets you know when you misspell variable names
use warnings; # Warns of issues (using undefined variables
use feature qw(say);
use Data::Dumper;
my @columns;
for my $data ( <DATA> ) {
my @data_list = split /\s*/, $data;
push @columns, \@data_list;
}
say join ", ", fetch_index( 0, @columns );
sub fetch_index {
my $entry = shift; #Entry you want from all arrays
my @array = @_;
my @values;
for my $array_ref ( @array ) {
push @values, ${array_ref}->[$entry];
}
return @values;
}
__DATA__
7 2 3
3 2 8
6 7 2
值。我将它们推入我的$entry
数组并返回。
答案 1 :(得分:2)
my @col;
while (<DATA>) {
push @col, (split ' ')[0];
# push @col, /(\S+)/; # split alternative
}
print "@col\n";
__DATA__
7 2 3
3 2 8
6 7 2
输出
7 3 6
答案 2 :(得分:0)
一旦你在这里的其他优秀帖子中吸收了有关匿名数组和参考的信息,你就可以开始玩得开心了。 例如你经常可以采用一种单行方式来工作:
perl -nE 'say [split]->[1] ' col_data.txt
将循环(-n
通过while(){}
中的数据创建隐式col_data.txt
循环,split
主题变量($_
)创建一系列每行中的匿名数组,然后打印第二个元素,例如“列”。
您可以使用autosplit command line option (-a
)将每行拆分为名为@F
的数组(助记符:“F
”表示“字段”)。在perl
的更高版本中,-a
表示隐式while
循环(-n
):
perl -anE 'say $F[1] ' col_data.txt
将等同于上一个命令 - 打印第二列:
<强>输出强>:
2
2
7
cut
有一个着名且简短的perl workalike,这是一个关于这个主题的更有特色的变体,并且有this Perl Monks thread。
答案 3 :(得分:0)
perl -a -F' ' -ne 'print "$F[0]\n";' data.txt
这里您$ F [0]是字段,您可以相应地更改它,您将获得预期的输出
答案 4 :(得分:-1)
我认为你非常接近。这就是我所做的(编辑以反映来自@Borodin的评论):
use strict;
use warnings;
sub getColumn {
my ($data, $col) = @_;
my @output = map $_->[$col], @{$data};
return @output;
}
my @data;
while (<DATA>){
push(@data, [split(' ',$_)]);
}
print join(' ', getColumn(\@data, 0), "\n");
print join(' ', getColumn(\@data, 1), "\n");
print join(' ', getColumn(\@data, 2), "\n");
__DATA__
7 2 3
3 2 8
6 7 2
该子例程getColumn
应该允许您检索任意列。当我用你的数据运行它时我得到了输出:
7 3 6
2 2 7
3 8 2