记录分隔符中的记录分隔符

时间:2016-06-06 00:40:29

标签: perl hash record bioinformatics

如何使用记录分隔符,然后同时使用子记录分隔符?也许这不是思考我想要做的事情的最佳方式。这是我的目标:

我想在指定的项目行中一次对单个制表符分隔项目执行while循环。对于制表符分隔项的每一行(行),我需要将所有while循环的结果打印到一个唯一的文件中。请允许以下示例帮助澄清。

我的输入文件将如下所示。它将被称为" Clustered_Barcodes.txt"

    TTTATGC TTTATGG TTTATCC TTTATCG
    TTTATAA TTTATAA TTTATAT TTTATAT TTTATTA
    CTTGTAA 

我的perl代码如下所示:

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

    open(INFILE, "<", "Clustered_Barcodes.txt") or die $!;

    my %hash = (
            "TTTATGC" => "TATAGCGCTTTATGCTAGCTAGC",
            "TTTATGG" => "TAGCTAGCTTTATGGGCTAGCTA",
            "TTTATCC" => "GCTAGCTATTTATCCGCTAGCTA",
            "TTTATCG" => "TAGCTAGCTTTATCGCGTACGTA",
            "TTTATAA" => "TAGCTAGCTTTATAATAGCTAGC",
            "TTTATAA" => "ATCGATCGTTTATAACGATCGAT",
            "TTTATAT" => "TCGATCGATTTATATTAGCTAGC",
            "TTTATAT" => "TAGCTAGCTTTATATGCTAGCTA",
            "TTTATTA" => "GCTAGCTATTTATTATAGCTAGC",
            "CTTGTAA" => "ATCGATCGCTTGTAACGATTAGC",
    );

    while(<INFILE>) {
            $/ = "\n";
            my @lines = <INFILE>;
            open my $out, '>', "Clustered_Barcode_$..fasta" or die $!;
            foreach my $sequence (@lines){
                   if (exists $hash{$sequence}){
                   print $out ">$sequence\n$hash{$sequence}\n";
                   }
            }
   } 

我想要的输出是三个不同的文件。 第一个文件将被调用&#34; Clustered_Barcode_1.fasta&#34;并且看起来像:

    >TTTATGC
    TATAGCGCTTTATGCTAGCTAGC 
    >TTTATGG 
    TAGCTAGCTTTATGGGCTAGCTA 
    >TTTATCC
    GCTAGCTATTTATCCGCTAGCTA
    >TTTATCG
    TAGCTAGCTTTATCGCGTACGTA 

请注意,这是格式化的,以便键前面有一个胡萝卜,然后在下一行是较长的关联序列(值)。此文件包含Clustered_Barcodes.txt

第一行中的所有序列

我的第三个文件应命名为&#34; Clustered_Barcode_3.fasta&#34;看起来如下:

    >CTTGTAA 
    ATCGATCGCTTGTAACGATTAGC 

当我运行我的代码时,它只需要输入文件中的第二行和第三行序列。如何从第一行开始(通过删除记录分隔符的\ n要求)?然后,我如何一次处理每个项目,然后将该行的结果打印到一个文件中?此外,如果有一种方法可以将序列数量合并到文件名中,那就太棒了。这将有助于我以后按大小组织文件。例如,名称可能类似于&#34; Clusterd_Barcodes_1_File_3_Sequences.fasta&#34;。

谢谢大家。

2 个答案:

答案 0 :(得分:3)

好的,所以这是一种方法:

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

标准序言。

my %hash = (
    "TTTATGC" => "TATAGCGCTTTATGCTAGCTAGC",
    "TTTATGG" => "TAGCTAGCTTTATGGGCTAGCTA",
    "TTTATCC" => "GCTAGCTATTTATCCGCTAGCTA",
    "TTTATCG" => "TAGCTAGCTTTATCGCGTACGTA",
    "TTTATAA" => "TAGCTAGCTTTATAATAGCTAGC",
    "TTTATAA" => "ATCGATCGTTTATAACGATCGAT",
    "TTTATAT" => "TCGATCGATTTATATTAGCTAGC",
    "TTTATAT" => "TAGCTAGCTTTATATGCTAGCTA",
    "TTTATTA" => "GCTAGCTATTTATTATAGCTAGC",
    "CTTGTAA" => "ATCGATCGCTTGTAACGATTAGC",
);

设置序列的哈希值。

my $infile = 'Clustered_Barcodes.txt';
open my $infh, '<', $infile or die "$0: $infile: $!\n";

打开文件进行阅读。

chomp(my @rows = readline $infh);
my $row_count = @rows;

将所有行拖入内存以获取序列数。如果序列太多,这种方法就不会起作用(因为你的内存不足(但这取决于你有多少RAM)。)

my $i = 1;
for my $row (@rows) {

循环上线。

    my @fields = split /\t/, $row;

将每一行拆分为由制表符分隔的字段。

    my $outfile = "Clustered_Barcodes_${i}_File_${row_count}_Sequences.fasta";
    $i++;
    open my $outfh, '>', $outfile or die "$0: $outfile: $!\n";

打开当前输出文件和增量计数器。

    for my $field (@fields) {
        print $outfh ">$field\n$hash{$field}\n" if exists $hash{$field};
    }

将每个字段(及其映射)写入outfile。

}

我们已经完成了。与原始代码的主要区别在于使用split /\t/foreach来循环一行中的字段。

我们也可以不吝啬地做到这一点:

while (my $row = readline $infh) {
    chomp $row;

逐行循环。这会将chomp(my @rows = readline $infh);中的4行替换为for my $row (@rows) {

但是现在我们已经丢失了$i$row_count变量,因此我们必须更改$outfile的初始化:

    my $outfile = "Clustered_Barcodes_$..fasta";

这应该是您需要的所有更改。 (通过阅读$row_count两次(第一次只是为了计数,然后seek回到开头),你可以在这种情况下得到$infh;这是作为练习阅读器。)

答案 1 :(得分:2)

我没有必要阅读我在这里看到的整个文件。你只需要遍历每一行的内容:

    while(my $line = <INFILE>) {
        chomp $line;
        open my $out, '>', "Clustered_Barcode_$..fasta" or die $!;
        foreach my $sequence ( split /\t/, $line ){
            if (exists $hash{$sequence}){
                print $out ">$sequence\n$hash{$sequence}\n";
            }
        }
    }