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 个基因列表(所以对第一个问题“是”并提供一个名称)然后对第二个问题回答“否”),我收到消息,即在-e 附近$genes2$genes3。我想-eand-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.
4

2 回答 2

1

尝试重写if (-e -s $genes1){if (-e $genes1 && -s $genes1){.

-e-s文件测试返回 1 表示真,'' 表示假,如果文件不存在,则返回未定义的值。原始代码似乎等同于(例如)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报告This is perl 5, version 16, subversion 3 (v5.16.3) built for MSWin32-x64-multi-thread。由于问题中的代码不完整,我在您的问题的答案中添加了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工作正常。问题是何时应用 hey$genes2以及$genes3何时没有提供文件。第 33 行和第 34 行的打印显示在文本上方的输出中At line 51,它们确认了这一点$genes2并且$genes3没有定义。它们由第open(...)23 行和第 27 行中的调用分配值,否则它们将保留在第 13 和 14 行声明时获得的未定义值。

在文件 test-e $genes1中,该值$genes1包含一个打开文件的句柄,因此测试是有效的。不需要第二个或第三个文件,因此open不为$genes2and执行 s $genes3,因此它们具有未定义的值。

测试可能应该更改为:

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

if ( defined $genes3 && -s $genes3){
于 2013-08-12T11:20:11.150 回答
0

考虑将 -e 和 -s 移动到单独if的块 - 检查文件是否存在于第一个块中并在此块中添加文件大小检查。例子,

# check for existence
if (-e $genes1)
{
    # check size only if file exists
    if (-s $genes1)
    {
        # processing takes place here
    }
}
于 2013-08-12T12:41:06.077 回答