计算在不放入数组的情况下从 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;
我已经假设了;
- 输出文件的第一个数字名称是输入文件行号
- 输出文件中的第二个数字名称是输入文件列号
- 输入哈希是数组的哈希,以涵盖多个序列的情况"matching"评论中提到的一个条形码
- 当条形码在散列中有匹配项时,输出文件将列出数组中的所有序列,每行一个。
据我所知,执行此操作的最简单方法是使用临时文件名构建输出文件,并在拥有所有数据后重命名它。根据 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
当提供的条形码有两个匹配项时,我在这里推测您想要什么。希望对您有所帮助。
为了记忆起见,我希望避免使用数组,但对于 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;
我已经假设了;
- 输出文件的第一个数字名称是输入文件行号
- 输出文件中的第二个数字名称是输入文件列号
- 输入哈希是数组的哈希,以涵盖多个序列的情况"matching"评论中提到的一个条形码
- 当条形码在散列中有匹配项时,输出文件将列出数组中的所有序列,每行一个。
据我所知,执行此操作的最简单方法是使用临时文件名构建输出文件,并在拥有所有数据后重命名它。根据 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().
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
当提供的条形码有两个匹配项时,我在这里推测您想要什么。希望对您有所帮助。