在Perl中逐行读取文件

时间:2018-04-29 10:38:42

标签: perl line readfile

我想用一行读取一个文件,但它只读取第一行。如何读取所有行?

我的代码:

open(file_E, $file_E);

while ( <file_E> ) {
    /([^\n]*)/;
    print $line1;
}

close($file_E);

2 个答案:

答案 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);