如何只从输入文件中存储某些列?

时间:2017-09-26 00:48:23

标签: perl parsing

我正在创建一个脚本,该脚本应该接收数据文件和列索引,读取并存储该列,然后对数据执行一些统计。我不确定如何指定我只想在Perl中存储特定列。到目前为止,这是我的代码:

#! /usr/bin/perl
use warnings;
use strict;
use feature qw(say);
use Scalar::Util qw(looks_like_number);

my ($FILE, $COLUMN_TO_PARSE) = @ARGV;

#check if file arg is present
if(not defined $FILE){
    die "Please specify file input $!";
} 
#check if column arg is present
if(not defined $COLUMN_TO_PARSE){
    die "Please specify column number $!";
}

unless(open(INPUT_FILE, "<", $FILE)){
        die "Couldn't open ", $FILE ," for reading!", $!;
}
my @data;
while(<INPUT_FILE>){
     # Only store $COLUMN_TO_PARSE, save to @data
}
close(INPUT_FILE);

作为参考,进来的数据看起来像这样(抱歉格式):

01 8 0 35 0.64 22

02 8 0 37 0.68 9

03 8 0 49 0.68 49

例如,如果我跑了

perl descriptiveStatistics.pl dataFile.txt 3

我希望[35,37,49]数组中包含@data

我偶然发现了this question,但它与我不具备的标题有关,而且不是非常有用的imo。有什么建议吗?

4 个答案:

答案 0 :(得分:1)

split是个不错的选择:

while (my $line = <INPUT_FILE>) {
    my @items = split(/\t/, $line);
    push @data,$items[$COLUMN_TO_PARSE];
}

答案 1 :(得分:1)

我已使用split()将输入拆分为记录列表。默认情况下,split()适用于$_并在空白处分割 - 这正是我们想要的。

然后我使用列表切片来获取您想要的列,并将其推送到您的阵列。

#! /usr/bin/perl

use warnings;
use strict;

# Check parameters
@ARGV == 2 or die "Please specify input file and column number\n";

my ($file, $column_to_parse) = @ARGV;

open my $in_fh, '<', $file
  or die "Couldn't open $file for reading: $!";

my @data;

while (<$in_fh>){
  push @data, (split)[$column_to_parse];
}

如果我是为自己写的,我想我会用while替换map循环。

my @data = map { (split)[$column_to_parse] } <$in_fh>;

更新:为了确保您获得了有效的列号(我认为这是一个好主意),您可能会写下这样的内容:

while (<$in_fh>){
  my @fields = split;
  die "Not enough columns in row $.\n" if $#fields < $column_to_parse;
  push @data, $fields[$column_to_parse];
}

答案 2 :(得分:0)

您可以设计匹配列的正则表达式模式,重复$COLUMN_TO_PARSE次,然后捕获列的内容并将其推送到数组@data

像这样:

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my @data;
my $COLUMN_TO_PARSE = 3;
while (<DATA>) {
    if (/([^\s]+\s+){$COLUMN_TO_PARSE}([^\s]+)/) {
        push @data, $2;
    } else {
        print("error wrong line format: $_\n");
    }
}
print Dumper(@data);

__DATA__
01 8 0 35 0.64 22
02 8 0 37 0.68 9
03 8 0 49 0.68 49

@data提供以下转储:

$VAR1 = '35';
$VAR2 = '37';
$VAR3 = '49';

$COLUMN_TO_PARSE基于零,如您的示例所示,并且作为副作用,如果请求的列不存在,则正则表达式将失败,从而为您提供错误处理。

答案 3 :(得分:0)

您可以使用split逐列获取数据。每列都存储在数组的连续索引中。

while(<INPUT_FILE>){
     my @columns = split(/\t/, $_);  #Assuming delimiter to tab

     print "First column====$columns[0]\n";
     print "Second column====$columns[1]\n";

}

处理您想要的任何列并存储到数组中。

相关问题