在Perl中读取和打印文本文件

时间:2013-09-10 17:43:35

标签: perl

我有一个简单的问题:

为什么第一个代码不打印文件的第一行但是第二行呢?

#! /usr/bin/perl

use warnings;
use strict;

my $protfile = "file.txt";
open (FH, $protfile);
while (<FH>) {
         print (<FH>);

}

#! /usr/bin/perl

use warnings;
use strict;

my $protfile = "file.txt";
open (FH, $protfile);
while (my $file = <FH>) {
         print ("$file");

}

4 个答案:

答案 0 :(得分:5)

上下文。

您的第一个程序通过读取第一行来测试FH上的文件结尾,然后在列表上下文中读取FH作为print的参数。这转换为整个文件,作为每个项目一行的列表。然后它再次测试EOF,很可能检测到它,然后停止。

你的第二个程序逐行迭代,每个程序在标量上下文中读取变量$file,并单独打印它们。它通过while语法中的特殊情况检测EOF。 (参见the documentation

中的代码示例

因此,在一个案例中,您的程序不打印第一行的具体原因是它在while的参数中丢失了。请注意,这两个程序的结构非常不同:第一个只运行一次while次迭代,而第二次只迭代一次。

PS:现在,管理文件的推荐方法倾向于词汇文件句柄(open my $file, 'name'; print <$file>;)。

答案 1 :(得分:3)

因为你正在使用&lt;&gt;来消费第一行操作员然后在打印中再次使用它,所以第一行已经消失但你没有打印它。 &LT;&GT;是readline运算符。您需要打印$ _变量,或者像在第二个代码中那样将其分配给已定义的变量。你可以重写第一个:

打印;

它会起作用,因为如果你不给它任何东西,print会使用$ _。

答案 2 :(得分:2)

标量上下文中使用时,<FH>会返回文件中的下一行。

列表上下文中使用时,<FH>会返回文件中所有剩余行的列表。

while (my $file = <FH>)是一个标量上下文,因为你正在分配一个标量。 while (<FH>)while(defined($_ = <FH>))的缩写,因此它也是标量上下文。 print (<FH>);使它成为一个列表上下文,因为你将它用作可以接受多个参数的函数的参数。

while (<FH>) {
    print (<FH>);
}

while部分将第一行读入$_(永不再使用)。然后print部分一次读取所有行,然后再将它们全部打印出来。然后再次检查while条件,但由于现在没有行,<FH>返回undef并且循环在一次迭代后退出。

while (my $file = <FH>) {
    print ("$file");
}

做了你可能期望的更多:读取然后在循环的每次迭代中打印一行。

顺便说一下,print $file;print ("$file");

相同

答案 3 :(得分:1)

while (<FH>) {
    print (<FH>);
}

改为使用:

while (<FH>) {
    print $_;
}