0

我正在尝试创建一个简单的脚本来读取包含书名记录的文本文件。每条记录都用一个普通的旧双空格 ( \r\n\r\n) 分隔。我需要计算文件中有多少条记录。

例如这里是输入文件:

record 1
some text


record 2 
some text
...

我正在使用正则表达式来检查回车符和换行符,但它不匹配。我究竟做错了什么?我无计可施。

sub readInputFile {

    my $inputFile = $_[0]; #read first argument from the commandline as fileName

    open INPUTFILE, "+<", $inputFile or die $!;    #Open File

    my $singleLine;
    my @singleRecord;
    my $recordCounter = 0;

    while (<INPUTFILE>) {                    # loop through the input file line-by-line
        $singleLine = $_;
        push(@singleRecord, $singleLine);    # start adding each line to a record array

        if ($singleLine =~ m/\r\n/) {        # check for carriage return and new line
            $recordCounter += 1;
            createHashTable(@singleRecord);  # send record make a hash table
            @singleRecord = ();              # empty the current record to start a new record
        }

    }

    print "total records : $recordCounter \n";
    close(INPUTFILE);
}
4

3 回答 3

1

听起来您正在 Linux 上处理一个 Windows 文本文件,在这种情况下,您想打开带有:crlf图层的文件,这会将所有 CRLF 行结尾转换为标准 Perl\n结尾。

如果您在 Windows 平台上读取 Windows 文件,那么转换已经为您完成,您将不会在已读取的数据中找到 CRLF 序列。如果您正在阅读 Linux 文件,那么无论如何都没有 CR 字符。

听起来您的记录也被空行分隔。将内置输入记录分隔符变量$/设置为空字符串将导致 Perl 一次读取整条记录。

我相信这个版本的子程序是你所需要的。请注意,熟悉 Perl 的人会感谢您在变量和子例程名称中使用小写字母和下划线。混合大小写通常保留用于包名称。

你没有显示create_hash_table,所以我不知道它需要什么数据。我已经将记录切碎并分成几行,并传递了记录中删除换行符的行列表。create_hash_table将整个记录作为单个字符串传递并根据需要处理它可能会更好。

sub read_input_file {

    my ($input_file) = @_;

    open my $fh, '<:crlf', $input_file or die $!;
    local $/ = '';

    my $record_counter = 0;

    while (my $record = <$fh>) {
        chomp;
        ++$record_counter;
        create_hash_table(split /\n/, $record);
    }
    close $fh;

    print "Total records : $record_counter\n";
}
于 2013-05-18T17:32:06.953 回答
0

您可以通过更改 Perl 的记录分隔符来更简洁地做到这一点,这将使循环一次返回一条记录,而不是一次返回一行。

例如,打开文件后:

local $/ = "\r\n\r\n";
my $recordCounter = 0;
$recordCounter++ while(<INPUTFILE>);    

$/保存 Perl 的全局记录分隔符,并且使用它限定它local允许您暂时覆盖它的值,直到封闭块结束时,它会自动恢复到以前的值。

但听起来您正在处理的文件实际上可能有“\n\n”记录分隔符,甚至“\r\r”。您需要为正在处理的任何文件正确设置记录分隔符。

于 2013-05-18T17:36:26.360 回答
0

如果您的文件不是数 GB 的巨大文件,最简单和最安全的方法是读取整个文件,并使用通用换行元字符 \R

这样,如果某些文件实际上使用 LF 而不是 CRLF(甚至是旧的 Mac 标准 CR),它也可以工作。

split如果您还需要实际记录,请使用它:

perl -ln -0777 -e 'my @records = split /\R\R/; print scalar(@records)' $Your_File

或者,如果您只想计算记录:

perl -ln -0777 -e 'my $count=()=/\R\R/g; print $count' $Your_File

有关更多详细信息,另请参阅我在此处对类似问题的其他回答。

于 2020-10-05T19:25:51.643 回答