【问题标题】:Record separator within a record separator记录分隔符内的记录分隔符
【发布时间】:2016-10-05 12:21:15
【问题描述】:

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

我想在指定的项目行中一次对单个制表符分隔的项目执行 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";
                   }
            }
   } 

我想要的输出是三个不同的文件。 第一个文件名为“Clustered_Barcode_1.fasta”,如下所示:

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

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

我的第三个文件应该命名为“Clustered_Barcode_3.fasta”,如下所示:

    >CTTGTAA 
    ATCGATCGCTTGTAACGATTAGC 

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

谢谢大家。

【问题讨论】:

    标签: perl hash record bioinformatics


    【解决方案1】:

    好的,这是一种方法:

    #!/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;
    

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

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

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

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

    【讨论】:

    • 那太好了。非常感谢您的回复。关于啜饮,我将有数千行文本输入代码。我将在服务器上执行此操作,并且可能有足够的 RAM,但我可能没有,这取决于我的数据集。有没有比啜饮更有效的记忆替代品?再次,我真的很感谢你的专业知识。谢谢。
    【解决方案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";
                }
            }
        }
    

    【讨论】:

    • 有没有办法修改这个,让输出文件的名字包含文件的行数?例如,输出文件“Clustered_Barcode_3_2_rows.fasta”中将只有 2 行,而输出文件“Clustered_Barcode_2_4_rows.fasta”中将有 4 行。谢谢,
    猜你喜欢
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多