[英]reading and printing a text file in Perl
I have simple question: 我有一个简单的问题:
#! /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");
}
Context. 语境。
Your first program tests for end-of-file on FH
by reading the first line, then reads FH
in list context as an argument to print
. 您的第一个程序通过读取第一行来测试FH
上的文件结尾,然后在列表上下文中读取FH
作为print
参数。 That translates to the whole file, as a list with one line per item. 这转换为整个文件,作为每个项目一行的列表。 It then tests for EOF again, most likely detects it, and stops. 然后它再次测试EOF,很可能检测到它,然后停止。
Your second program iterates by line, each one read in scalar context to variable $file
, and prints them individually. 你的第二个程序逐行迭代,每个程序在标量上下文中读取变量$file
,并单独打印它们。 It detects EOF by a special case in the while
syntax. 它通过while
语法中的特殊情况检测EOF。 (see the code samples in the documentation ) (参见文档中的代码示例)
So the specific reason why your program doesn't print the first line in one case is that it's lost in the argument to while
. 因此,在一个案例中你的程序不打印第一行的具体原因是它在while
的参数中丢失了。 Do note that the two programs' structure is pretty different: the first only runs a single while
iteration, while the second iterates once per line. 请注意,这两个程序的结构非常不同:第一个只while
迭代时运行一个,而第二个在每行迭代一次。
PS: nowadays, the recommended way to manage files tends towards lexical filehandles ( open my $file, 'name'; print <$file>;
). PS:现在,管理文件的推荐方法倾向于词汇文件句柄( open my $file, 'name'; print <$file>;
)。
Because you are comsuming the first line with the <> operator and then using it again in the print, so the first line has already gone but you are not printing it. 因为你正在使用<>操作符来第一行,然后在打印中再次使用它,所以第一行已经消失但是你没有打印它。 <> is the readline operator. <>是readline运算符。 You need to print the $_ variable, or assign it to a defined variable as you are doing in the second code. 您需要打印$ _变量,或者像在第二个代码中那样将其分配给已定义的变量。 You could rewrite the first: 你可以重写第一个:
print; 打印;
And it would work, because print uses $_ if you don't give it anything. 它会起作用,因为如果你不给它任何东西,print会使用$ _。
When used in scalar context , <FH>
returns the next single line from the file. 在标量上下文中使用时, <FH>
将返回文件中的下一行。
When used in list context , <FH>
returns a list of all remaining lines in the file. 在列表上下文中使用时, <FH>
返回文件中所有剩余行的列表。
while (my $file = <FH>)
is a scalar context, since you're assigning to a scalar. while (my $file = <FH>)
是一个标量上下文,因为你正在分配一个标量。 while (<FH>)
is short for while(defined($_ = <FH>))
, so it is also a scalar context. while (<FH>)
是while(defined($_ = <FH>))
缩写while(defined($_ = <FH>))
,因此它也是标量上下文。 print (<FH>);
makes it a list context, since you're using it as argument to a function that can take multiple arguments. 使它成为一个列表上下文,因为你将它用作可以接受多个参数的函数的参数。
while (<FH>) {
print (<FH>);
}
The while
part reads the first line into $_
(which is never used again). while
部分将第一行读入$_
(从不再使用)。 Then the print
part reads the rest of the lines all at once, then prints them all out again. 然后print
部件一次读取所有行,然后再次打印出来。 Then the while
condition is checked again, but since there are now no lines left, <FH>
returns undef
and the loop quits after just one iteration. 然后再次检查while
条件,但由于现在没有剩下的行, <FH>
返回undef
并且循环在一次迭代后退出。
while (my $file = <FH>) {
print ("$file");
}
does more what you probably expect: reads and then prints one line during each iteration of the loop. 做更多你可能期望的事情:在循环的每次迭代中读取然后打印一行。
By the way, print $file;
顺便说一句, print $file;
does the same as print ("$file");
与print ("$file");
while (<FH>) {
print (<FH>);
}
use this instead: 改用它:
while (<FH>) {
print $_;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.