要将多个文件存储到数组中,我通常使用:
@files = glob("*.txt");
my @ID;
for my $file(@files) {
open IN, '<', $file or die "$!";
push @ID, $_ while (<IN>);
}
哪种方法正常。
但是,如果我不想推送整个$_
并仅存储特定字段,我该怎么办?
我尝试拆分$_
并推送特定字段,例如$F[2]
以及拆分$_
并重新加入其中的特定元素并推送结果:
@files = glob("*.txt");
my @ID;
for my $file(@files) {
open IN, '<', $file or die "$!";
my @F = split(' ', $_);
$fields = join "\t", @F[0,1,2,3];
push @ID, $fields while (<IN>);
}
但是,当使用第二个代码块打印时,@ID
为空。
答案 0 :(得分:4)
您尝试在设置$ _之前拆分$ _。您需要将该代码移动到while循环中:
@files = glob("*.txt");
my @ID;
for my $file(@files) {
open IN, '<', $file or die "$!";
while (<IN>) {
my @F = split(' ', $_);
$fields = join "\t", @F[0,1,2,3];
push @ID, $fields;
}
}
答案 1 :(得分:1)
它不是空的。
$VAR1 = [
"\t\t\t",
"\t\t\t",
...
"\t\t\t"
];
但它并不包含你想要的东西。
您尝试拆分您阅读的每一行,但是在您阅读文件之前就这样做了!修正:
while (<IN>) {
my @F = split(' ', $_);
my $fields = join "\t", @F[0,1,2,3];
push @ID, $fields;
}
始终使用use strict; use warnings qw( all );
!这会发现你的问题。
Use of uninitialized value $_ in split at a.pl line 7.
答案 2 :(得分:1)
这些代码片段更加整齐地写成
my @ID;
for my $file ( glob '*.txt' ) {
open my $fh, '<', $file or die $!;
push @ID, <$fh>;
}
和
my @ID;
for my $file ( glob '*.txt' ) {
open my $fh, '<', $file or die $!;
push @ID, join "\t", (split)[0 .. 3] while <$fh>;
}
请注意,我使用了 lexical 文件句柄,当它们超出范围时会隐式关闭,因此无需编写明确的close
在前一种情况下,每个数组元素仍然附加一个换行符,可能需要使用chomp @ID
删除
在后一种情况下,最好将每个字段列表存储为数组,而不是将它们组合成单个字符串,然后可能需要稍后再次拆分以分别访问字段。那看起来像是
push @ID, [ (split)[0..3] ] while <$fh>;