一直在使用以下脚本,但仍然无法理解文件句柄形式的两种不同“种类”背后的含义。任何见解都将受到高度赞赏。
#! usr/bin/perl
use warnings;
use strict;
open (FH, "example.txt") or die $!;
while (<FH>) {
my @line = split (/\t/, $_); {
print "@line","\n";
}
}
输出符合预期:@line
数组包含来自example.txt
的第1,2,3行的元素。当我被告知open (FH, example.txt)
不如open (my $fh, '<', 'example.txt')
时,我改变了它,但随后出现了混乱。
根据我的发现,$fh
为scalar
并包含example.txt
中的所有信息。当我将数组分配给$fh
时,数组将example.txt
中的每一行存储为数组中的一个组件。但是,当我尝试将组件进一步拆分为“更多组件”时,我收到错误/警告消息“use of uninitialized value
”。下面是显示错误/警告消息的实际脚本。
open (my $fh, '<', 'example.txt') or die $!;
foreach ($fh) {
my @line = <$fh>;
my $count = 0;
for $count (0..$#line) {
my @line2 = split /\t/, $line[$count];
print "@line2";
print "$line2[0]";
}
}
print "@line2"
显示预期输出,但print "$line2[0]"
调用错误/警告消息。我想如果@line2
是一个真正的数组,$line2[0]
应该没问题。但为什么“未初始化的价值”??
任何帮助将不胜感激。非常感谢你。
已添加 - 以下是“实际”脚本(我重新运行它并且警告就在那里)
#! usr/bin/perl
use warnings;
use strict;
open (my $fh, '<', 'example.txt') or die $!;
foreach ($fh) {
my @line = <$fh>;
print "$line[1]";
my $count = 0;
for my $count (0..$#line) {
my @line2 = split /\t/, $line[$count];
print "@line2";
#my $line2_count = $#line2;
#print $line2_count;
print "$line2[3]";
}
}
警告仍为use of uninitialized value $line2[3] in string at filename.pl line 15, <$fh> line3
。
答案 0 :(得分:1)
在第二个示例中,您正在列表上下文中读取文件句柄,我认为这是您问题的根源。
my $line = <$fh>;
从文件句柄中读取一行。
my @lines = <$fh>;
读取所有文件。 你以前的例子,感谢
while (<FH>) {
有效地做了第一种情况。
但是在第二个例子中,你正在做第二件事。
答案 1 :(得分:-2)
AFAIK,你应该总是使用
while (<FH>) {
# use $_ to access the content
}
或更好
while(my $single_line = <FH>) {
# use $single_line to access the content
}
因为逐行读取,首先在内存中加载所有内容并在之后迭代它。
即使在EOF或错误上返回undef,解释器在未明确完成时也会添加对undef的检查。
因此,虽然您可以毫无问题地加载多千兆字节的日志文件,并且不会浪费RAM,而不能使用需要迭代数组的for循环。
至少这是我多年前读过的Perl书中的记忆。