Regex 从文件读取perl哈希数组
我正在尝试读取多个具有相同格式的文件,并希望基于regex进行一些统计 i、 e我想计算[]范围内的类似项目Regex 从文件读取perl哈希数组,regex,perl,foreach,hashtable,Regex,Perl,Foreach,Hashtable,我正在尝试读取多个具有相同格式的文件,并希望基于regex进行一些统计 i、 e我想计算[]范围内的类似项目 NC_013618 NC_013633 ([T(nad6 trnE ,cob trnT ,)]) C_013481 NC_013479 ([T(trnP ,rrnS trnF trnV rrnL nad1 trnI ,)]) NC_013485 NC_003159 ([T(trnC ,trnY ,)]) NC_013554 NC_013254 ([T(trnR ,trnN ,)]) N
NC_013618 NC_013633 ([T(nad6 trnE ,cob trnT ,)])
C_013481 NC_013479 ([T(trnP ,rrnS trnF trnV rrnL nad1 trnI ,)])
NC_013485 NC_003159 ([T(trnC ,trnY ,)])
NC_013554 NC_013254 ([T(trnR ,trnN ,)])
NC_013607 NC_013618 ([T(nad6 trnE ,cob trnT ,)])
问题是我没有得到正确的值,下面是我的代码:
use strict;
use warnings;
my %data;
@FILES = glob("../mitos-crex/*.out");
foreach my $file (@FILES) {
local $/ = undef;
open my $fh, '<', $file;
$data{$file} = <$fh>;
}
my @t;
my $c = 0;
foreach my $line (keys %data) {
foreach my $l ($data{$line}) {
print $l."\n";
($t[$c]) = $l =~ m/(\[.*\])/;
$c++;
}
}
#the problem is here the counter is not giving the right value
print $c;
my %counts;
$counts{$_}++ for @t;
使用严格;
使用警告;
我的%数据;
@FILES=glob(“../mitos-crex/*.out”);
foreach my$文件(@FILES){
本地$/=undef;
打开my$fh,“计数器给出了正确的值。您的问题是您正在读取文件(一次读取所有文件),但只存储找到的第一个值:
($t[$c]) = $data{$line} =~ m/(\[.*\])/; # only finds first value in file
正确循环每个文件,并对每一行使用上面的正则表达式,或者执行以下操作:
push @t, ($data{$line} =~ m/(\[.*\])/g);
你应该始终使用
use strict;
use warnings;
并解决由此产生的错误/警告。不这样做是个坏主意,只会在代码中隐藏问题,而不会解决问题
此外,您还应注意以下声明:
foreach $l ($data{$line}) {
只迭代一次,因为这里的每个“行”都是一个完整的文件,$data{$line}
是一个标量值之外的值。此外,您使用$l
作为别名进行迭代,但仍然使用$data{$line}
在循环内部,这使得循环完全冗余。计数器给出了正确的值。您的问题是您正在读取文件(一次读取所有文件),但只存储找到的第一个值:
($t[$c]) = $data{$line} =~ m/(\[.*\])/; # only finds first value in file
正确循环每个文件,并对每一行使用上面的正则表达式,或者执行以下操作:
push @t, ($data{$line} =~ m/(\[.*\])/g);
你应该始终使用
use strict;
use warnings;
并解决由此产生的错误/警告。不这样做是个坏主意,只会在代码中隐藏问题,而不会解决问题
此外,您还应注意以下声明:
foreach $l ($data{$line}) {
只迭代一次,因为这里的每个“行”都是一个完整的文件,$data{$line}
是一个标量值之外的值。此外,您使用$l
作为别名进行迭代,但仍然使用$data{$line}
在循环内部,这使得循环完全冗余。首先,始终使用严格的和使用警告
。这一措施对于所有编程都至关重要,因为它会很快暴露出简单的问题,否则您可能会忽略这些问题或在调试上浪费时间。如果您是We’在你的计划中寻求他人的帮助
您似乎混淆了将整个文件读入一个字符串和一个行数组。您编写它的方式是,每个元素$data{file}
都是一个包含文件所有数据的标量值,然后尝试使用foreach$l($data{$line}{…})对其进行迭代
只执行一次,因此只能在文件中找到第一个[…]
字符串
通常我会说,您不应该以这种方式读取所有文件数据,因为问题可能有更好的流式解决方案,但我不知道您还想使用捕获的数据做什么,因此我的解决方案遵循您自己的设计
我认为您需要将数据拖入一个虚拟数组,而不是标量,然后在循环中对其进行迭代。您必须保留$/
的定义,以便以行形式读取文件,并使用[]
构建一个匿名数组。然后您可以使用对每个我的$line(@{$data{$file}}{…}进行迭代
use strict;
use warnings;
my %data;
my @files = glob("../mitos-crex/*.out");
foreach my $file (@files) {
open my $fh, '<', $file or die $!;
$data{$file} = [ <$fh> ];
}
my $c = 0;
my @t;
foreach my $file (keys %data) {
foreach my $line (@{ $data{$file} }) {
($t[$c]) = $line =~ /(\[.*\])/;
$c++;
}
}
print $c;
my %counts;
$counts{$_}++ for @t;
使用严格;
使用警告;
我的%数据;
my@files=glob(“../mitos-crex/*.out”);
foreach my$文件(@files){
打开我的$fh,首先,始终使用严格的
和使用警告
。这一措施对于所有编程来说都是至关重要的,因为它会很快揭示一些简单的问题,否则您可能会忽略这些问题或在调试上浪费时间。如果您在程序中寻求他人的帮助,这一点尤其正确,也是一种简单的礼貌
您似乎混淆了将整个文件读入一个字符串和一个行数组。您编写它的方式是,每个元素$data{file}
都是一个包含文件所有数据的标量值,然后尝试使用foreach$l($data{$line}{…})对其进行迭代
只执行一次,因此只能在文件中找到第一个[…]
字符串
通常我会说,您不应该以这种方式读取所有文件数据,因为问题可能有更好的流式解决方案,但我不知道您还想使用捕获的数据做什么,因此我的解决方案遵循您自己的设计
我认为您需要将数据拖入一个虚拟数组,而不是标量,然后在循环中对其进行迭代。您必须保留$/
的定义,以便以行形式读取文件,并使用[]
构建一个匿名数组。然后您可以使用对每个我的$line(@{$data{$file}}{…}进行迭代
use strict;
use warnings;
my %data;
my @files = glob("../mitos-crex/*.out");
foreach my $file (@files) {
open my $fh, '<', $file or die $!;
$data{$file} = [ <$fh> ];
}
my $c = 0;
my @t;
foreach my $file (keys %data) {
foreach my $line (@{ $data{$file} }) {
($t[$c]) = $line =~ /(\[.*\])/;
$c++;
}
}
print $c;
my %counts;
$counts{$_}++ for @t;
使用严格;
使用警告;
我的%数据;
my@files=glob(“../mitos-crex/*.out”);
foreach my$文件(@files){
打开我的$fh,'我怀疑$data{$file}=;
不能满足您的要求。您能在打印后添加一个打印并检查它是否包含您期望的内容吗?添加使用strict;使用warnings;
并解决出现的错误/警告。然后重新发布您的问题。请使用适当的缩进。@triple I printed$l并给出正确的输出请不要修复ori中的问题基纳尔问题。你收到的答案变得无关紧要,这使得这个问题在帮助别人怀疑$data{$file}时很有用=;
不能满足您的要求。您能在打印后添加一个打印并检查它是否包含您期望的内容吗?添加使用strict;使用warnings;
并解决出现的错误/警告。然后重新发布您的问题。请使用适当的缩进。@triple I printed$l并给出正确的输出请不要修复ori中的问题基纳尔问题。你得到的答案变得无关紧要,这使得这个问题在帮助他人方面变得有用