我有一个脚本,我在其中询问用户是否要输入文件。如果他这样做&该文件不是空的,我想使用此文件并打开输出文件的结果。我想重复这个问题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个基因列表时(对于第一个问题'和'提供名称'是'是')&amp;然后回答'否'到第二个问题),我得到的信息是在$genes2
和$genes3
附近的-e中使用了一个单位化值。我想-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.
答案 0 :(得分: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)。由于问题中的代码不完整,我在问题prompting multiple questions to user (yes/no & file name input)的答案中添加了 amon 编写的提示代码。我还添加了一些print语句来显示代码中的流程。最后,我更改了第一组嵌套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
的{{1}}和 - s
工作正常。问题是当没有提供文件时,嘿被应用于$genes1
和$genes2
。第33和34行的打印件显示在文本$genes3
正上方的输出中,并确认未定义At line 51
和$genes2
。它们由第23行和第27行中的$genes3
调用分配值,否则它们将保留在第13和14行声明时获得的未定义值。
在文件测试open(...)
中,值-e $genes1
包含打开文件的句柄,因此测试有效。不需要第二个或第三个文件,因此不会对$genes1
和open
执行$genes2
,因此它们具有未定义的值。
测试应该改为:
$genes3
和
if ( defined $genes1 && -s $genes1){
if ( defined $genes2 && -s $genes2){
答案 1 :(得分:0)
考虑将-e和-s移动到单独的if
块 - 检查文件是否存在于第一个块中,并在此块中添加文件大小检查。例如,
# check for existence
if (-e $genes1)
{
# check size only if file exists
if (-s $genes1)
{
# processing takes place here
}
}