【问题标题】:How to go to a specific line in a multi-line string variable (Perl)?如何转到多行字符串变量(Perl)中的特定行?
【发布时间】:2024-01-14 18:03:01
【问题描述】:

我正在使用

将文本文件读入 SCALAR 变量
open FILE, "<", $filename or print("Error opening $filename");
read FILE, my $buffer, -s $filename;    
close FILE;

稍后我会计算SCALAR 变量中的行数。如何在不迭代的情况下转到 SCALAR 变量中的特定行?

【问题讨论】:

  • 除非你有固定宽度的线条,否则如果不通过它以某种方式进行迭代,就无法知道 X 行从哪里开始。但这似乎是XY problem;也许您应该准确解释您要达到的目标。您是否尝试替换文件中的文本位?正在搜索匹配行?删除第 n 个之后的所有行?完全不同的东西?
  • 另外,您似乎完全忽略了 ikegami's advice 关于如何改进此代码的问题。
  • 查找最后一行,匹配字符串,计算总行数——所有这些都是为了进一步分析代码......
  • 您可以通过逐行遍历文件来完成所有这些操作,无需将整个内容读入标量。也许您在这个问题中真正想问的是,“如何从文件中获取倒数第二行?”
  • 我还需要行数。

标签: perl text-files line scalar


【解决方案1】:

您最初提出的问题的答案是,除非您正在处理一个固定宽度的文件,否则您不能在不迭代的情况下跳到某一行以某种方式

但是,根据您的 cmets,似乎不需要首先将整个文件读入标量。您可以通过像这样简单地遍历文件来获得倒数第二行和总行数:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

my ($count, @previous);
while (<DATA>) {
    chomp;

    $count++;

    push @previous, $_;
    shift @previous if @previous > 2;
}

say "Count: $count";
say "Second-to-last line: $previous[0]";

__DATA__
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.

输出:

Count: 6
Second-to-last line: fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in

为简单起见,我使用了特殊的__DATA__ 块而不是外部文件。要读取上述文件,请执行以下操作:

open my $fh, '<', '/path/to/file' or die "Failed to open file: $!";

while (<$fh>) {
    ...
}

close $fh;

为什么这比将整个文件读入标量更好?如果您的文件很大,一次将整个文件全部读入内存可能会很昂贵。除非您有充分的理由不这样做,否则通常最好一次读取一行文件并随时处理它们。

【讨论】:

    最近更新 更多