我想用一行读取一个文件,但它只读取第一行。如何读取所有行?
open(file_E, $file_E);
while ( <file_E> ) {
/([^\n]*)/;
print $line1;
}
close($file_E);
答案 0 :(得分:1)
让我们从查看代码开始。
open(file_E, $file_E);
while ( <file_E> ) {
/([^\n]*)/;
print $line1;
}
close($file_E);
在第一行,您使用bareword文件句柄$file_E
打开名为file_E
的文件。只要文件成功打开,这应该可以工作。最好还是以两种方式检查此操作是否成功:将use autodie;
放在脚本的顶部(但是在代码与此级别的错误处理不兼容的地方冒险应用其语义) ),或将您的open
更改为如下所示:
open(file_E, $file_E) or die "Failed to open $file_E: $!\n";
现在,如果您无法打开该文件,您将收到一条错误消息,有助于追踪问题。
接下来让我们看一下while
循环,因为在这里您遇到的问题导致您遇到的错误。在while
循环的第一行,你有这个:
while ( <file_E> ) {
通过咨询perldoc perlsyn
,你会发现这条线是特殊的,实际上是这样做的:
while (defined($_ = <file_E>)) {
因此,您的代码在连续迭代时隐式地将每行分配给$_
。另外,通过咨询perldoc perlop
,您会发现当调用匹配运算符(/.../
或m/.../
)而未使用=~
显式绑定匹配时,匹配将绑定{ {1}}。然而,到目前为止,这么好。但是,您实际上并没有对匹配做任何有用的事情。匹配运算符将返回布尔真值/假值,表示匹配是否成功。并且因为您的模式包含捕获括号,它将捕获一些内容到捕获变量$_
中。但是你永远不会测试比赛是否成功,你也没有再次提到$1
。
在接下来的行中,您执行以下操作:$1
。在您的代码中,print $line1
被分配了一个值?因为它永远不会被赋予你向我们展示的价值。
我只能猜测你的意图是迭代文件的行,捕获行但没有尾随的换行符,然后打印它。您似乎希望在没有任何换行符的情况下打印它,以便将所有输入文件打印为单行输出。
$line1
无需捕获任何内容 - 如果捕获所做的只是抓取换行符的所有内容,您只需使用open my $input_fh_e, '<', $file_E or die "Failed to open $file_E: $!\n";
while(my $line = <$input_fh_e>) {
chomp $line;
print $line;
}
close $input_fh_e or die "Failed to close $file_E: $!\n";
开始删除换行符。
在我的例子中,我使用了一个词法文件句柄(一个词法范围的文件句柄,用chomp
声明)。这在现代Perl中通常是一种更好的做法,因为它避免使用裸字,避免可能的命名空间冲突,并确保在词法范围关闭后句柄将立即关闭。
我还使用了my
的'三个arg'版本,这更安全,因为它消除了open
用于打开管道或执行其他恶意或简单无意的shell操作的可能性
我建议您使用$file_E
启动脚本,因为如果您这样做了,那么在编译时您会收到一条错误消息,告诉您use strict;
从未声明过。同时使用$line1
启动您的脚本,以便在您为其分配值之前尝试打印use warnings
时收到警告。
代码中的大多数问题都将在perldoc perlintro
中讨论,只需键入$line1
,即使安装了Perl,也可以从命令行到达。通读perldoc perlintro
通常需要20-40分钟。如果在开始编写Perl代码之前有一个文档应构成必需的阅读,那么该阅读可能包括perlintro
。
答案 1 :(得分:-1)
另一种选择,请注意$ _将包含换行符,因此如果您不想在$行中使用换行符,则需要将其删除:
open(file_E, $file_E);
while ( <file_E> ) {
my $line = $_;
print $line;
}
close($file_E);