如果在之前的讨论中已经回答了这个问题,那我对perl和道歉很新。我有一个脚本需要在循环外使用声明的变量,但只有一个循环正在工作,即使我已经在循环之外声明了变量,代码是:
my $sample;
open(IN, 'ls /*_R1_*.gz |');
while (my $sample = <IN>) {
chomp $sample;
print "sample = $sample\n";
my $fastq1="${sample}"; #need to use fastq1 later on hence it's declared here
my $sample2;
open(IN, 'ls /*_R2_*.gz |');
while (my $sample2 = <IN>) {
chomp $sample2;
print "sample2 = $sample2\n";
my $fastq2="${sample2}"; #need to use fastq2 later on hence it's declared here
}
}
Sample2有效但sample1没有,只输出第一个样本,然后循环进入sample2,输出为:
sample =/sample1_R1_001.fastq.gz
sample2 =/sample1_R2_001.fastq.gz
sample2 =/sample2_R2_001.fastq.gz
sample2 =/sample3_R2_001.fastq.gz
等。
有人可以解决这个问题吗?
由于
答案 0 :(得分:2)
根据您的评论,我认为您的问题可能是您在循环中声明$fastq1
和$fastq2
。这意味着它们将超出循环范围,并且无法访问。你需要这样的东西:
my ($fastq1, $fastq2);
while ( ... ) {
....
$fastq1 = $sample;
}
请注意,这只会保存该变量循环中的最后一个值。当然,其他循环迭代将覆盖其他循环。如果要保存更多值,请使用数组或散列。
关于您的代码的其他一些注释。
你应该总是使用
use strict;
use warnings;
不这样做是一个非常糟糕的主意,因为它只会隐藏错误和警告,而不是解决它们。
my $sample;
您将此变量声明两次。
open(IN, 'ls /*_R1_*.gz |');
这在所有可能的级别上都很糟糕:
ls
的输出很脆弱且不便携推荐的解决方案:使用opendir + readdir或glob:
for my $files (</*_R1_*.gz>) { ... }
# or
opendir my $dh, "/" or die $!;
while (my file = readdir $dh) {
next unless $file =~ /_R1_.*\.gz$/;
...
}
my $fastq1 = "${sample}";
my
的变量时,它只保留单循环迭代的值。既然你从不使用这个变量,我认为你打算在循环之外使用它。但它将超出范围。这可以写成
my $fastq1 = $sample;
但是您可能希望在while循环之外声明这些变量,否则它们将超出范围。你应该知道,这只会保存这些变量的最后一个值。
另外,正如Rohit所说,你的循环是嵌套的,我认为这不是你想要的。这很可能是因为你没有使用正确的文本编辑器来编写你的代码,所以你的缩进都搞砸了,很难看出一个循环结束的地方。遵循罗希特的建议。
答案 1 :(得分:1)
您正在关闭第二个while循环结束后的第一个while循环。因此,您的第二个while循环成为第一个while循环的一部分,其中,您将文件处理程序 - IN 重新分配给另一个文件。而且由于你在内部while循环中耗尽它,你的外部while循环永远不会再次运行。
你应该在开始下一个之前关闭大括号:
while(my $sample = <IN>){
chomp $sample;
print "sample = $sample\n";
my $fastq1="${sample}";
} # You need this
my $sample2;
open(IN, 'ls /data_n2/vmistry/Fluidigm_Exome/300bp_fastq/*_R2_*.gz |');
while(my $sample2 = <IN>){
chomp $sample2;
print "sample2 = $sample2\n";
my $fastq2="${sample2}";
}
# } # Remove this