2013-02-19 127 views
-2

如果在前面的討論中已經回答了這個問題,我對perl很抱歉並且道歉。我有一個需要使用循環外聲明的變量的腳本,但只有一個迴路工作,儘管我已經聲明在循環外部變量,代碼:Perl while while循環不起作用

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 
    } 
} 

樣本2的作品,但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

您的預期產量是多少? – darch 2013-02-19 16:40:23

回答

1

您關閉也先while循環第二次結束後循環。因此,您的第二個while循環成爲第一個while循環的一部分,其中,您將文件處理程序-IN重新分配給另一個文件。而且,由於你在內部while循環中耗盡了它,所以你的outer 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 
+0

是的,我已經嘗試過,它確實有效,但$ fastq1和$ fastq2變量稍後不會處理: – 2013-02-19 16:44:58

2

從您的意見,我認爲你的問題可能是,你聲明$fastq1$fastq2內循環。這意味着它們將超出循環範圍,並且無法訪問。你需要類似的東西:

my ($fastq1, $fastq2); 
while (...) { 
    .... 
    $fastq1 = $sample; 
} 

請注意,這隻會保存該變量循環中的最後一個值。其他人當然會覆蓋每個循環迭代。如果您有更多值要保存,請使用數組或散列。

關於您的代碼的一些其他說明。


你應該總是使用

use strict; 
use warnings; 

不這樣做是一個非常糟糕的主意,因爲它只會隱藏的錯誤和警告,不解決這些問題。


my $sample; 

你聲明這個變量的兩倍。


open(IN, 'ls /*_R1_*.gz |'); 

這僅僅是壞在所有可能的層面:

  • 系統調用總是最不理想的選擇,除非不存在替代
  • Perl有讀取文件的許多方式名稱
  • 解析ls的輸出很脆弱而且不便攜
  • 通過打開打開系統命令的結果將使用此方法複合其他缺陷。

建議的解決辦法:使用任何執行opendir + readdir的或水珠:

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所說,你的循環是嵌套的,我認爲這不是你想要的。這很可能是因爲你沒有使用正確的文本編輯器來編寫代碼,所以你的縮進全部搞砸了,很難看到一個循環結束的地方。按照Rohit的建議。