在perl中混淆文件句柄

时间:2015-06-06 15:25:15

标签: arrays perl filehandle

一直在使用以下脚本,但仍然无法理解文件句柄形式的两种不同“种类”背后的含义。任何见解都将受到高度赞赏。

#! 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')时,我改变了它,但随后出现了混乱。

根据我的发现,$fhscalar并包含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

2 个答案:

答案 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书中的记忆。