我正在创建一个脚本,该脚本应该接收数据文件和列索引,读取并存储该列,然后对数据执行一些统计。我不确定如何指定我只想在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。有什么建议吗?
答案 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";
}
处理您想要的任何列并存储到数组中。