-1

在我的 Perl 脚本中,我有一个双无限 while 循环。我使用菱形运算符从文件中读取行。但不知何故,如果我的脚本到达文件的最后一行,它不会返回 undef,而是永远挂起。

如果我将代码减少到单个 while 循环,则不会发生这种情况。所以我想知道我是否做错了什么,或者这是否是语言的已知限制。(这实际上是我的第一个 perl 脚本。)

下面是我的脚本。它旨在计算 fasta 文件中 DNA 序列的大小,但在任何其他具有多行文本的文件中都可以观察到挂起行为。

Perl 版本 5.18.2

从命令行调用,如perl script.pl file.fa

$l = <>;
while (1) {
    $N = 0;
    while (1) {
        print "Get line";
        $l = <>;
        print "Got line";
        if (not($l)) {
            last;
        }
        if ($l =~ /^>/) {
            last;
        }

        $N += length($l);
    }
    print $N;
    if (not($N)) {
        last;
    }
}

我放了一些调试打印语句,以便您可以看到打印的最后一行是“Get line”,然后它挂起。

4

2 回答 2

4

欢迎来到 Perl。

您的代码的问题是您无法逃避外循环。到达文件末尾时<>将返回。undef此时,您的内部循环结束,外部循环将其送回。强制进一步读取会导致<>开始查看STDIN哪个永远不会发送 EOF,因此您的循环将永远继续。

由于这是您的第一个 Perl 脚本,我将用一些评论为您重写它。Perl 是一门很棒的语言,您可以编写一些很棒的代码,但主要是由于它的年代久远,有些旧样式不再被推荐。

use warnings; # Warn about coding errors
use strict; # Enforce good style
use 5.010; # Enable modernish (10 year old) features

# Another option which mostly does the same as above.
# I normally do this, but it does require a non-standard CPAN library
# use Modern::Perl;

# Much better style to have the condition in the while loop
# Much clearer than having an infinite loop with break/last statements
# Also avoid $l as a variable name, it looks too much like $1
my $count = 0; # Note variable declaration, enforced by strict
while(my $line = <>) {
    if ($line =~ /^>/) {
        # End of input block, output and reset
        say $count;
        $count = 0;
    } else {
        $count += length($line);
    }
}

# Have reached the end of the input files
say $count;
于 2018-11-18T22:05:46.210 回答
0

试试“echo | perl script.pl file.fa”。

在我的代码中对我有同样的“问题”。

从标准输入获取 EOF。

于 2021-01-04T20:11:09.643 回答