计算文件中以用户定义的匹配开始和结束的序列

Counting sequences in a file beginning and ending with a user defined match

我有一个名为 "test.fas":

的 DNA 序列的 fasta 格式文件
>test1
GCCATTACAGAACATCAGTCACAGTACGTACTGTGTTCTGCCGTGCTGTCTA
>test2
CGGATGAAGCGCCAATCGTACGTACAATAAGTTGCCTAAAGTGTTTCA
>test3
ATGCATGCATGC

我还有一个制表符分隔的引物序列文件,名为 "primers.txt":

GCCATTACAGAACATCAGTCACA TAGACAGCACGGCAGAACAC
CGGATGAAGCGCCAATC   TGAAACACTTTAGGCAACTTATT

此 primers.txt 文件中的每一行都是一个引物对,可能与 fasta 文件中序列的开始和结束相匹配。每行的第二个引物也需要反向补充才能匹配 fasta 文件中的任何内容。查看primers.txt中第一行的第一个引物对,在反向互补第二个引物后,它应该与test.fas文件中test1的序列相匹配。

我想要做的是将这两个文件提供给 perl 程序,并获得一个输出文件,其中包含使用 primers.txt 文件中的引物对发现序列的次数.在这种情况下,我的输出文件将列出:

1
1

实际上我在一个文件中有 650000 个序列,还有 170 个引物集要从文件中搜索和枚举。因此,我想要一个 170 行长的输出文件,每行列出在 fasta 文件中为特定引物对找到匹配项的次数。基本上,对于 primer.txt 文件中的每一行,计算以该引物对开始和结束的序列在 fasta 文件中出现的次数。这是我到目前为止想出的:

#!/usr/bin/perl
use strict;
use warnings;

print "Name of the FASTA file: ";
chomp( my $multifasta = <STDIN> );

print "Name file with primers: ";
chomp( my $pulls = <STDIN> );

print "Name of the output file: ";
chomp( my $out = <STDIN> );

open(MULTIFASTA,$multifasta) || die ;
  my $seq = do { local $/; <MULTIFASTA>};
  close MULTIFASTA;

open(PULLS,$pulls) || die;
  while (my $line = <PULLS>){
  chomp $line;
  my @primers = split (/\t/,$line);
  my $revcomp = reverse $primers[1];
  $revcomp =~ tr/ATGCatgc/TACGtacg/;  #reverse complement the reverse primer
  my $matches = () = $seq =~ /^\Q$primers[0].*\Q$primers[1]$/; #How to structure the regex? 
  open(OUTFILE,">>$out");
  print OUTFILE "$matches\n";   
}

我的 outfile 结尾是这样的:

0
0

我显然搞砸了。我很快就陷入了尝试在 Google 上发现的不同事物的陷阱,而没有牢牢掌握对代码的影响,此时我迷路了。这是因为很快就需要答案,而且对编程知之甚少。我从阅读中了解到我应该阅读整个文件以扫描与本地的匹配项,并且我需要使用 \Q 在 perl 的正则表达式中搜索变量。无论如何,我们将不胜感激任何帮助或指点。谢谢 -

从所有引物创建一个正则表达式。此外,将引物存储在哈希中,值将是行号。然后,遍历 fasta 文件并尝试匹配正则表达式。如果匹配,则使用散列检索引物的行号,并使用另一个散列记录每个行号的匹配数。最后,只报告数字:

#!/usr/bin/perl
use warnings;
use strict;

my ($fasta_file, $primers_file) = @ARGV;

my %primer;
open my $primers_fh, '<', $primers_file or die $!;
while (<$primers_fh>) {
    chomp;
    my ($first, $second) = split /\t/;
    $second = reverse $second;
    $second =~ tr/actgACTG/tgacTGAC/;
    undef $primer{$first}{$.};
    undef $primer{$second}{$.};
}

my $primers_count = $.;
my $regex =  join '|', keys %primer;

my %seen;
open my $fasta_fh, '<', $fasta_file or die $!;
while (<$fasta_fh>) {
    if (/^($regex)/) {
        ++$seen{$_} for keys %{ $primer{} };
    }
}

for my $line_number (sort { $a <=> $b } 1 .. $primers_count) {
    print $seen{$line_number} // 0, "\n";
}

我认为您误解了 \Q(和 \E)的作用。它用于自动反斜杠正则表达式特殊字符。它不适用于 "searching for a variable in a regex"。 Perl 已经在本地识别正则表达式中的变量。这里不需要 \Q

my $matches = () = $seq =~ /^\Q$primers[0].*\Q$primers[1]$/;

像这样的基本正则表达式匹配 returns 1 或 0 表示真假。它不会 return 你想要的匹配数组。为此,您需要 g 全局修饰符。

您可能还需要 .* 在这里使用 .*? 来代替。

您在这里也错误地使用了 ^$。这会强制您的引物仅匹配(多行)字符串的开头和结尾,而不匹配其中的行。这就是为什么您的比赛得到 0(假)的原因。