我在目录中有五个fasta文件,我可以将其成功放入一个数组中。当我尝试通过foreach循环连续打开所有文件时,要对每个文件执行正则表达式,只有目录中的第一个文件似乎打开进行处理。此外,当我尝试在第一个文件中打印整个序列时(通过未显示的诊断打印语句),忽略序列的前半部分。仅打印序列的后一部分。如果有人对如何克服这个问题有所了解,我将非常感激。这是我的代码到目前为止的样子。
#!/usr/bin/perl
use warnings;
use strict;
use diagnostics;
my $dir = ("/Users/roblogan/Documents/FakeFastaFilesAgain");
my @TrimmedSequences;
my @ArrayofFiles = glob "$dir/*";
#print join("\n", @ArrayofFiles), "\n"; # this is a diagnostic test print statement
foreach my $file (@ArrayofFiles){
open (my $sequence, '<', $file) or die $!; # open each file in the array
while (my $line = <$sequence>) {
$line =~ s/\R//g; # get rid of new line breaks
if ($line =~ m/(CTCCCA)[TAGC]+(TCAGGA)/) { # search file contents
push(@TrimmedSequences, $line); # push the match into another array
close $file;
}
}
}
print join("\n", @TrimmedSequences), "\n";
答案 0 :(得分:1)
在删除close语句时,测试代码(或类似代码)可以正常工作。使用关闭会在找到匹配后立即中断循环。每个文件只留下一个结果。
另请注意,您根本不需要致电关闭。当变量$ sequence失去范围时,文件将被关闭。
应该使用 chomp
来摆脱换行符
这是我的测试代码。请注意一些编辑。
#!/usr/bin/perl
use strict;
use warnings;
my $files = (".");
my @files = grep { $_ =~ /\.pl/} glob "$files/*"; #added to filter out the directies in test directory, can be ignored
my @lines;
#use for in perl not foreach
for my $file (@files){
open my $fh, '<', $file or die $!;
while(my $line = <$fh>){
chomp($line); #Use chomp to remove newlines
if($line =~ /use/){
push @lines, $line; #no need to call close at all, the filehandle is closed when it loses scope
}
}
}
print join("\n", @lines) . "\n";
在我的测试目录中按预期执行并打印目录中的perl文件中的所有use语句。
答案 1 :(得分:0)
您正在使用错误的变量$file
(文件名,字符串)而不是$sequence
(文件的文件句柄)调用close。
此外,close
调用位置错误,您正在读取循环中间关闭文件句柄。如果您确实只想在每个文件中找到第一个匹配的行,请关闭文件句柄并从while循环中断(last
)。如果要在所有文件中找到所有匹配的行:
foreach my $file (@ArrayofFiles){
open (my $sequence, '<', $file) or die $!;
while (my $line = <$sequence>) {
$line =~ s/\R//g;
if ($line =~ m/(CTCCCA)[TAGC]+(TCAGGA)/) {
push(@TrimmedSequences, $line);
}
}
close $sequence or die $!;
}