gpt4 book ai didi

perl - 跳过文件的前 x 行和最后 y 行

转载 作者:行者123 更新时间:2023-12-04 04:23:52 25 4
gpt4 key购买 nike

我正在对文本文件(可能达到 1GB 范围)进行一些简单的解析。我将如何跳过前 N 行,更重要的是,跳过最后(不同的)N 行?我确信我可以打开文件并计算行数,然后用 $_ < total_row_count -N 做一些事情,但这似乎非常低效。顺便说一句,我几乎是 perl 新手。

最佳答案

文件是一个字节序列,没有“行”的概念。其中一些字节被视为“行”分隔符(换行符),这就是软件为我们提供“逻辑”行的方式。因此,没有办法知道文件中有多少行 - 没有读取并计算它们。

一种简单而幼稚的方法是逐行阅读并计数

open my $fh, '<', $file  or die "Can't open $file: $!";

my $cnt;
++$cnt while <$fh>;

使用 $. variable 的更快版本

1 while <$fh>;
my $cnt = $.;

在一个合理的桌面上,一个 1.1 Gb 的文本文件需要 2.5 到 3 秒。

我们可以通过读取更大的 block 并计算换行符来加快速度

open my $fh, '<', $file  or die "Can't open $file: $!";

my $cnt;
NUM_LINES: {
my $len = 64_000;
my $buf;

$cnt += $buf =~ tr/\n//
while read $fh, $buf, $len;

seek $fh, 0, 0;
};

在相同的硬件和 Perl 版本上,这仅用了半秒多一点。

我已经将它放在一个 block 中以限定不需要的变量,但它应该在一个子中,然后您可以在其中检查文件句柄的位置,然后在计数后将其返回那里(这样我们就可以计算“其余” 文件中某个点的行,然后处理可以继续)等。它还应该包括在每次调用时对 read 操作的检查。

我认为 Gb 大文件的半秒开销一点也不坏。

不过,您可以更快地进行,但代价是变得更加困惑。获取文件大小(元数据,因此不涉及读取)和 seek 到估计为结束前所需行数的位置(不涉及读取)。那很可能不会到达正确的位置,因此请阅读到最后以计算行数并进行调整,然后再寻找(更远或更近)。重复直到你到达需要的地方。

open my $fh, "<", $file; 
my $size = -s $file;

my $estimated_line_len = 80;
my $num_last_lines = 100;

my $pos = $size - $num_last_lines*$estimated_line_len;

seek $fh, $pos, 0;

my $cnt;
++$cnt while <$fh>;

say "There are $cnt lines from position $pos to the end";

# likely need to seek back further/closer ...

我猜这应该让您在 100 毫秒内到达那里。请注意,$pos 可能在一行内。

然后,一旦您知道行数(或结束前所需行数的位置),请执行 seek $fh, 0, 0 并处理。或者真的把它放在一个 sub 中,它把文件句柄放回返回之前的位置,如前所述。

关于perl - 跳过文件的前 x 行和最后 y 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58441214/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com