计算在不放入数组的情况下从 split 派生的项目数

Count the number of items derived from split without putting into an array

为了记忆起见,我希望避免使用数组,但对于 while 循环的每次传递,仍会获得从 split 函数派生的项目数。
最终目标是根据序列数过滤输出文件,序列数可以通过文件的行数、出现的胡萝卜数或换行符数等推导出来。 下面是我的代码:

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

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

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

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

输入文件 "Clustered_Barcodes.txt" 打开后如下所示:

    TTTATGC TTTATGG TTTATCC TTTATCG
    TTTATAA TTTATAA TTTATAT TTTATAT TTTATTA
    CTTGTAA 

代码将产生三个输出文件,"Clustered_Barcode_1.txt"、"Clustered_Barcode_2.txt" 和 "Clustered_Barcode_3.txt"。输出文件的示例可能是第三个也是最后一个文件,如下所示:

    >CTTGTAA 
    ATCGATCGCTTGTAACGATTAGC 

我需要一些方法来修改我的代码,以识别文件中出现的行数、胡萝卜或序列数,并将其用于文件标题。上述序列的新标题可能类似于 "Clustered_Barcode_Number_3_1_Sequence.txt"

PS- 我在上面的代码中手动生成了散列,试图让事情变得更简单。如果您想查看原始代码,请看这里。输入文件格式类似于:

   >TAGCTAGC 
    GCTAAGCGATGCTACGGCTATTAGCTAGCCGGTA  

这里是设置散列的代码:

    my $dir = ("~/Documents/Sequences");          
    open(INFILE, "<", "~/Documents/Clustered_Barcodes.txt") or die $!; 

    my %hash = (); 

    my @ArrayofFiles = glob "$dir/*";            #put all files from the specified directory into an array

    #print join("\n", @ArrayofFiles), "\n";       #this is a diagnostic test print statement

    foreach my $file (@ArrayofFiles){                                 #make hash of barcodes and sequences
        open (my $sequence, $file) or die "can't open file: $!";        
        while (my $line = <$sequence>) {    
            if ($line !~/^>/){ 
                my $seq = $line; 
                $seq =~ s/\R//g;
                #print $seq;           
                $seq =~ m/(CATCAT|TACTAC)([TAGC]{16})([TAGC]+)([TAGC]{16})(CATCAT|TACTAC)/;  
                $hash{} = ;                    
            }
        }
    } 

    while(<INFILE>){ 

等等

您的哈希结构不适合您的问题,因为您有多个相同 ID 的条目。例如 TTTATAA 哈希 ID 在您的 %hash.

中有 2 个条目

要解决此问题,请使用 数组的散列 创建散列。

中更改您的哈希创建代码
$hash{} = ;

push(@{$hash{}}, );

现在更改 while 循环中的代码

while(my $line = <INFILE>){ 
        chomp $line; 
        open my $out, '>', "Clustered_Barcode_$..txt" or die $!;

        my %id_list;
        foreach my $sequence (split /\t/, $line){
            $id_list{$sequence}=1;

        }
        foreach my $sequence(keys %id_list)
        {
            foreach my $val (@{$hash{$sequence}})
            {
                    print $out ">$sequence\n$val\n";
            }
        }
}

您可以使用正则表达式来获取计数:

my $delimiter = "\t";
my $line = "zyz pqr abc xyz";
my $count = () = $line =~ /$delimiter/g;  # $count is now 3
print $count;

我已经假设了;

  1. 输出文件的第一个数字名称是输入文件行号
  2. 输出文件中的第二个数字名称是输入文件列号
  3. 输入哈希是数组的哈希,以涵盖多个序列的情况"matching"评论中提到的一个条形码
  4. 当条形码在散列中有匹配项时,输出文件将列出数组中的所有序列,每行一个。

据我所知,执行此操作的最简单方法是使用临时文件名构建输出文件,并在拥有所有数据后重命名它。根据 perl cookbook, the easiest way to create temporary files is with the module File::Temp.

此解决方案的关键是按列索引移动出现在行上的条形码列表,而不是简单地遍历列表本身的常用 perl 方法。为了获得实际的条形码,列号 $col 用于索引回 @barcodes,它是通过在白色 space 上拆分线而创建的。 (请注意,splitting on a single space 是 perl 的特殊情况,以模拟其前身之一的行为,awk(删除了前导白色 space 并且拆分为白色 space,而不是单个 space)).

这样我们就可以从 the perl special variable, $. We can then use these to rename the file using the builtin, rename().

得到列号(从 1 开始索引)和行号
use warnings;
use strict;
use diagnostics;
use File::Temp qw(tempfile);

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

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

my $cbn = "Clustered_Barcode_Number";
my $trailer = "Sequence.txt";

while (my $line = <INFILE>) {
    chomp $line ;
    my $line_num = $. ;

    my @barcodes = split " ", $line ;
    for my $col ( 1 .. @barcodes )  {
        my $barcode = $barcodes[ $col - 1 ];  # arrays indexed from 0

        # skip this one if its not in the hash
        next unless exists $hash{$barcode} ;
        my @sequences =  @{ $hash{$barcode} } ;

        # Have a hit - create temp file and output sequences
        my ($out, $temp_filename) = tempfile();
        say $out ">$barcode" ;
        say $out $_ for (@sequences) ;
        close $out ;

        # Rename based on input line and column
        my $new_name = join "_", $cbn, $line_num, $col, $trailer  ;
        rename ($temp_filename, $new_name) or
            warn "Couldn't rename $temp_filename to $new_name: $!\n" ;
    }
}
close INFILE

样本输入数据中的所有条形码在哈希中都有匹配项,因此当我 运行 这样做时,我得到第 1 行的 4 个文件、第 2 行的 5 个文件和第 3 行的 1 个文件。

Clustered_Barcode_Number_1_1_Sequence.txt
Clustered_Barcode_Number_1_2_Sequence.txt
Clustered_Barcode_Number_1_3_Sequence.txt
Clustered_Barcode_Number_1_4_Sequence.txt
Clustered_Barcode_Number_2_1_Sequence.txt
Clustered_Barcode_Number_2_2_Sequence.txt
Clustered_Barcode_Number_2_3_Sequence.txt
Clustered_Barcode_Number_2_4_Sequence.txt
Clustered_Barcode_Number_2_5_Sequence.txt
Clustered_Barcode_Number_3_1_Sequence.txt

Clustered_Barcode_Number_1_2_Sequence.txt 例如有:

>TTTATGG
TAGCTAGCTTTATGGGCTAGCTA

Clustered_Barcode_Number_2_5_Sequence.txt有:

>TTTATTA
GCTAGCTATTTATTATAGCTAGC

Clustered_Barcode_Number_2_3_Sequence.txt - 将哈希键与两个序列匹配 - 具有以下内容;

>TTTATAT
TCGATCGATTTATATTAGCTAGC
TAGCTAGCTTTATATGCTAGCTA

当提供的条形码有两个匹配项时,我在这里推测您想要什么。希望对您有所帮助。