2013-08-12 32 views
0

我有一個腳本,在其中詢問用戶是否要輸入文件。如果他這樣做&該文件不是空的比我想要使用此文件並打開輸出文件的結果。我想重複這個問題3次,以便用戶可以導入最多3個文件。這是我的腳本看起來像:只有在輸入文件不爲空的情況下才打開輸出文件

(12) my $genes1; 
(13) my $genes2; 
(14) my $genes3; 

(16) if (prompt_yn("Do you want to import a genelist for filtering?")){ 
(17)  my $genelist1 = prompt("Give the name of the first genelist file:\n"); 
(18)  print "genelist1 = \"$genelist1\"\n"; 
(19)  open($genes1,'<',$genelist1) or die "Could not open file $genelist1 $!"; 
(20)  if (prompt_yn("Do you want to import another gene list file?")){ 
(21)   my $genelist2 = prompt("Give the name of the second genelist file:\n"); 
(22)   print "genelist2 = \"$genelist2\"\n"; 
(23)   open($genes2,'<',$genelist2) or die "Could not open file $genelist2 $!"; 
(24)   if (prompt_yn("Do you want to import another gene list file?")){ 
(25)     my $genelist3 = prompt("Give the name of the third genelist file:\n"); 
(26)     print "genelist3 = \"$genelist3\"\n"; 
(27)     open($genes3,'<',$genelist3) or die "Could not open file $genelist3 $!"; 
(28)   } 
(29)  } 
(30) } 
(32) print "genes1 = \"$genes1\"\n"; 
(33) print "genes2 = \"$genes2\"\n"; 
(34) print "genes3 = \"$genes3\"\n"; 
(45) my $genelist1filter; 
(46) my $genelist1restfilter; 
(47) my $genelist2filter; 
(48) my $genelist2restfilter; 
(49) my $genelist3filter; 
(50) my $genelist3restfilter; 
(51) printf "At line %d\n", __LINE__; 
(52) print "genes1 is ", defined $genes1 ? "defined\n" : "not defined\n"; 
(53) print "genes2 is ", defined $genes2 ? "defined\n" : "not defined\n"; 
(54) print "genes3 is ", defined $genes3 ? "defined\n" : "not defined\n"; 
(56) if (-e $genes1 && -s $genes1){ 
(57) printf "At line %d\n", __LINE__; 
(58) open($genelist1filter, '+>', "genelist1_missense_nonsense_frameshift_inframe_startloss_stoploss.txt") || die "Can't write new file: $!"; printf "At line %d\n", __LINE__; 
(59) #first output file 
(60) open($genelist1restfilter, '+>', "notingenelist_missense_nonsense_frameshift_inframe_startloss_stoploss.txt") || die "Can't write new file: $!"; #second output file 
(61) } # same for $genes2 and $genes3 
(62) printf "At line %d\n", __LINE__; 

# line56 to 62 is repeated for $genes2(lines63-69) and for $genes3(lines70-77) 

(183)# genelist2 filtering 
    my %hash2=(); 
    while(<$genes2>){ 
    chomp; 
    #next unless -z $_; 
    my $keyfield = $_; 
    $hash2{$keyfield}++; 
(190) } 

(201)# genelist3 filtering 
    my %hash3=(); 
    while(<$genes3>){ 
    chomp; 
    #next unless -z $_; 
    my $keyfield = $_; 
    $hash3{$keyfield}++; 
(208) } 

現在,當我測試這個腳本,並讓用戶輸入1 genelist(所以「是」第一個問題&提供姓名)&然後回答「不」的第二個問題),我得到的消息是在-e附近使用了一個單位化的值,在$genes2$genes3附近。我想-e-s有什麼問題來檢查文件是否存在並且不是空的?有人可以對此發表評論嗎?

這是輸出的樣子(基於編輯從AndrianHHH腳本)

Do you want to import a genelist for filtering? (Y/N): y 
Give the name of the first genelist file: 
genelist1.txt 
genelist1 = "genelist1.txt" 
Do you want to import another gene list file? (Y/N): n 
genes1 = "GLOB(0x134c568)" 
Use of uninitialized value $genes2 in concatenation (.) or string at filtering.pl line 33, <STDIN> line 3. 
genes2 = "" 
Use of uninitialized value $genes3 in concatenation (.) or string at filtering.pl line 34, <STDIN> line 3. 
genes3 = "" 
At line 51 
genes1 is defined 
genes2 is not defined 
genes3 is not defined 
At line 57 
At line 58 
At line 62 
Use of uninitialized value $genes2 in -e at filtering.pl line 63, <STDIN> at line 3                          At line 69 
Use of uninitialized value $genes3 in -e at filtering.pl line 70, <STDIN> line 3. 
At line 77 
Use of uninitialized value $genes2 in <HANDLE> at filtering.pl line 185. 
readline() on unopened filehandle at filtering.pl line 185. 
Use of uninitialized value $genes3 in <HANDLE> at filtering.pl line 203. 
readline() on unopened filehandle at filtering.pl line 203. 

回答

1

嘗試重寫if (-e -s $genes1){if (-e $genes1 && -s $genes1){

-e-s文件測試返回1表示true,''表示false,如果該文件不存在,則返回未定義值。原始代碼似乎等於(例如)my $a=1; my $b=1; if($a $b) {,這可能不是預期的。此外,省略參數-e或 - s可使其工作於$_。因此建議在這個答案的第一行重寫。

隨着上述變化,看起來$genes1是未定義的。但是這看起來不太可能,因爲上面的open ... or die ...

我將在Perl調試運行程序,或者只是在測試之前添加一條語句,像這樣的:

print "genes1 is ", defined $genes1 ? "defined\n" : "not defined\n"; 

更新

您提供的代碼似乎做工精細用Perl其中perl -v報告這是爲MSWin32-x64-多線程構建的perl 5,版本16,subversion 3(v5.16.3)。由於問題中的代碼不完整,我在的問題答案中添加了amon的提示代碼。我還添加了一些打印語句來顯示代碼的流程。最後,我更改了第一組嵌套的if語句的縮進,以更清楚地顯示結構。

請檢查問題中的代碼是否是您正在運行的代碼的真實副本。還請檢查您使用的提示碼是否修改$genes1變量。

use strict; 
use warnings; 

my ($genes1, $genes2, $genes3); 

if (prompt_yn("Do you want to import a genelist for filtering?")){ #prompt_yn is a subroutine which I already tested & it worked 
    my $genelist1 = prompt("Give the name of the first genelist file:\n"); 
    print "genelist1 = \"$genelist1\"\n"; 
    open($genes1,'<',$genelist1) or die "Could not open file $genelist1 $!"; 
    if (prompt_yn("Do you want to import another gene list file?")){ 
     my $genelist2 = prompt("Give the name of the second genelist file:\n"); 
     print "genelist2 = \"$genelist2\"\n"; 
     open($genes2,'<',$genelist2) or die "Could not open file $genelist2 $!"; 
     if (prompt_yn("Do you want to import another gene list file?")){ 
      my $genelist3 = prompt("Give the name of the third genelist file:\n"); 
      print "genelist2 = \"$genelist3\"\n"; 
      open($genes3,'<',$genelist3) or die "Could not open file $genelist3 $!"; 
     } 
    } 
} 

print "genes1 = \"$genes1\"\n"; 
print "genes2 = \"$genes2\"\n"; 
print "genes2 = \"$genes3\"\n"; 


my ($genelist1filter, $genelist1restfilter, $genelist2filter, $genelist2restfilter, $genelist3filter, $genelist3restfilter) ; 

printf "At line %d\n", __LINE__; 
print "genes1 is ", defined $genes1 ? "defined\n" : "not defined\n"; 

if (-e $genes1 && -s $genes1){ 
    printf "At line %d\n", __LINE__; 
    open($genelist1filter, '+>', "genelist1_missense_nonsense_frameshift_inframe_startloss_stoploss.txt") || die "Can't write new file: $!"; printf "At line %d\n", __LINE__; 
    #first output file 
    open($genelist1restfilter, '+>', "notingenelist_missense_nonsense_frameshift_inframe_startloss_stoploss.txt") || die "Can't write new file: $!"; #second output file 
} # same for $genes2 and $genes3 

printf "At line %d\n", __LINE__; 


sub prompt { 
    my ($query) = @_; # take a prompt string as argument 
    local $| = 1; # activate autoflush to immediately show the prompt 
    print $query; 
    chomp(my $answer = <STDIN>); 
    return $answer; 
} 


sub prompt_yn { 
    my ($query) = @_; 
    my $answer = prompt("$query (Y/N): "); 
    return lc($answer) eq 'y'; 
} 

另一個更新:

在修訂的問題顯示的輸出顯示發生了什麼。 -e和 - s適用於$genes1工作正常。問題是當沒有提供文件時,它們被應用於$genes2$genes3。第33行和第34行的打印輸出顯示在文本At line 51正上方的輸出中,它們確認沒有定義$genes2$genes3。它們是由線23和27的open(...)呼叫分配的值,否則會被留下當線13和14

在文件測試-e $genes1宣佈他們獲得未定義的值,該值$genes1包含的句柄打開文件,因此測試是有效的。沒有第二個或第三個文件是需要的,所以open s不執行$genes2$genes3,所以他們有未定義的值。

測試也許應該改爲:

if (defined $genes1 && -s $genes1){ 
if (defined $genes2 && -s $genes2){ 

if (defined $genes3 && -s $genes3){ 
+0

在添加語句時更改此 – user1987607

+0

時仍會收到相同的消息,它將顯示:「定義基因1」。之後,我得到了和以前一樣的信息 – user1987607

+0

我使用的是perl 5版本14 subversion 2.這確實是我的代碼。我可以給你發送輸出嗎? – user1987607

0

不妨將-e和-s分離if塊 - 檢查該文件中的第一個塊中存在並在此塊中添加文件大小檢查。例如,

# check for existence 
if (-e $genes1) 
{ 
    # check size only if file exists 
    if (-s $genes1) 
    { 
     # processing takes place here 
    } 
} 
+0

Perlfun(在ActivePerl v5.16.3中)文件測試運算符的狀態「這個一元運算符接受一個參數,一個文件名,一個文件句柄或一個dirhandle,並測試關聯的文件以查看是否有關於它的真實情況。所以文件句柄應該工作正常。 – AdrianHHH

+0

我的不好,編輯。感謝您指出了這一點。 –

+0

@JTG在更改時仍然會收到相同的消息 – user1987607

相關問題