如何从表格数据打印特定列

How to print a particular column from tabular data

我正在尝试通过在 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 

我该怎么做?

我认为你非常接近。这就是我所做的(编辑以反映@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
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

始终使用 use strict;use warnings;!!

您有几个问题:

push( @col, @xz );

在这种情况下,您 丢失了 您在 @xz 数组中的信息。在此循环之后,您最终得到一个如下所示的数组:

@col = ( 7, 2, 3, 3, 2, 8, 6, 7, 2);

因此,当您打印时:

print "$col[0]\n";

你得到了第零个元素:7。

我们可以使用 reference:

来保存数据的结构
#! /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

在这里你看到我包含了 Data::Dumper 来打印出 @columns:

的结构
$VAR1 = [
          [
            '7',
            '2',
            '3'
          ],
          [
            '3',
            '2',
            '8'
          ],
          [
            '6',
            '7',
            '2'
          ]
      ];

如您所见,@columns 数组中的每个条目现在都是另一个数组。但是,打印出 $columns[0] 数组引用不会打印出您想要的内容。相反,它将打印第零个数组引用:7、2、3,而不是每个数组引用的第零个元素:7、3、6。

为此,我们需要一个 子例程 ,它将通过 @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 值。我将它们推入我的 @values 数组和 return 那个。

一旦您吸收了此处其他优秀帖子中有关匿名数组和引用的信息,您就可以开始玩得开心了。 例如你通常可以得到一种单行方法来工作:

perl -nE 'say [split]->[1] ' col_data.txt  

将通过 col_data.txt 中的数据循环(-n 创建一个隐式 while(){} 循环),split 主题变量 ($_) 创建一个每行中的一系列匿名数组,然后打印第二个元素,或者 "column" 例如。

您可以使用 autosplit command line option (-a) 将每一行拆分为一个名为 @F 的数组(助记:“F”代表 "Field")。在 perl 的更高版本中,-a 意味着隐式 while 循环 (-n):

perl -anE 'say $F[1] ' col_data.txt

将等同于之前的命令 - 打印第二列:

输出:

2
2
7

cut 有一个著名且简短的 perl workalike,它是这个主题的更有特色的变体,还有 this Perl Monks thread

perl -a -F' ' -ne 'print "$F[0]\n";' data.txt

here you $F[0] is field you can change it accordingly you will get the expected output