如何删除文件的最后5行

发布于 2025-01-06 14:15:53 字数 217 浏览 0 评论 0原文

我有几个使用 perl 将文本打印到文件的命令。在这些 print 命令中,我有一个 if 语句,如果该语句为真,则应删除我当前正在写入的文件的最后 5 行。要删除的行数始终为 5。

if ($exists == 0) {
  print(OUTPUT ???) # this should remove the last 5 lines
}

I have several commands printing text to a file using perl. During these print commands I have an if statement which should delete the last 5 lines of the file I am currently writing to if the statement is true. The number of lines to delete will always be 5.

if ($exists == 0) {
  print(OUTPUT ???) # this should remove the last 5 lines
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

Saygoodbye 2025-01-13 14:15:53

您可以使用 Tie::File

use Tie::File;
tie my @array, 'Tie::File', filename or die $!;

if ($exists == 0) {
    $#array -= 5;
}

打印时可以使用相同的数组,但使用 push 代替:

push @array, "line of text";

You can use Tie::File:

use Tie::File;
tie my @array, 'Tie::File', filename or die $!;

if ($exists == 0) {
    $#array -= 5;
}

You can use the same array when printing, but use push instead:

push @array, "line of text";
z祗昰~ 2025-01-13 14:15:53
$ tac file | perl -ne 'print unless 1 .. 5' | tac > file.tailchopped
$ tac file | perl -ne 'print unless 1 .. 5' | tac > file.tailchopped
苍风燃霜 2025-01-13 14:15:53

我能想到的唯一明显的方法:

  1. 锁定文件,扫描 向后查找位置并使用
    截断
  2. 不要直接打印到文件,而是通过缓冲区
    至少有 5 行长,然后修剪缓冲区。
  3. 打印一个标记,表示“忽略最后五行”。
    在使用缓冲区读取所有文件之前先对其进行处理,如 #2 中所示。

所有这些都非常繁琐,但这恐怕就是平面文件的本质。

华泰

Only obvious ways I can think of:

  1. Lock file, scan backwards to find a position and use
    truncate.
  2. Don't print to the file directly, go through a buffer
    that's at least 5 lines long, and trim the buffer.
  3. Print a marker that means "ignore the last five lines".
    Process all your files before reading them with a buffer as in #2

All are pretty fiddly, but that's the nature of flat files I'm afraid.

HTH

自由范儿 2025-01-13 14:15:53

作为替代方案,打印除最后 5 行之外的整个文件:

open($fh, "<", $filename) or die "can't open $filename for reading: $!";
open($fh_new, ">", "$filename.new") or die "can't open $filename.new: $!";
my $index = 0; # So we can loop over the buffer
my @buffer;
my $counter = 0;
while (<$fh>) {
    if ($counter++ >= 5) {
        print $fh_new $buffer[$index];
    }
    $buffer[$index++] = $_;
    $index = 0 if 5 == $index;
}
close $fh;
close $fh_new;
use File::Copy;
move("$filename.new", $filename) or die "Can not copy $filename.new to $filename: $!";

As an alternative, print the whole file except last 5 lines:

open($fh, "<", $filename) or die "can't open $filename for reading: $!";
open($fh_new, ">", "$filename.new") or die "can't open $filename.new: $!";
my $index = 0; # So we can loop over the buffer
my @buffer;
my $counter = 0;
while (<$fh>) {
    if ($counter++ >= 5) {
        print $fh_new $buffer[$index];
    }
    $buffer[$index++] = $_;
    $index = 0 if 5 == $index;
}
close $fh;
close $fh_new;
use File::Copy;
move("$filename.new", $filename) or die "Can not copy $filename.new to $filename: $!";
知你几分 2025-01-13 14:15:53

File::ReadBackwards+truncate 对于大文件来说是最快的,对于短文件来说可能与其他任何东西一样快。

use File::ReadBackwards qw( );

my $bfh = File::ReadBackwards->new($qfn)
   or die("Can't read \"$qfn\": $!\n");

$bfh->readline() or last for 1..5;

my $fh = $bfh->get_handle();
truncate($qfn, tell($fh))
   or die $!;

Tie::File 最慢,并且使用大量内存。避免该解决方案。

File::ReadBackwards+truncate is the fastest for large files, and probably as fast as anything else for short files.

use File::ReadBackwards qw( );

my $bfh = File::ReadBackwards->new($qfn)
   or die("Can't read \"$qfn\": $!\n");

$bfh->readline() or last for 1..5;

my $fh = $bfh->get_handle();
truncate($qfn, tell($fh))
   or die $!;

Tie::File is the slowest, and uses a large amount of memory. Avoid that solution.

只想待在家 2025-01-13 14:15:53

你可以尝试这样的事情:

open FILE, "<", 'filename';
if ($exists == 0){
 @lines = <FILE>;
 $newLastLine = $#lines - 5;   
 @print = @lines[0 .. $newLastLine];
 print "@print";
}

或者甚至缩短:

open FILE, "<", 'filename';
@lines = <FILE>;
if ($exists == 0){
 print "@lines[0 .. $#lines-5]";
}

you can try something like this:

open FILE, "<", 'filename';
if ($exists == 0){
 @lines = <FILE>;
 $newLastLine = $#lines - 5;   
 @print = @lines[0 .. $newLastLine];
 print "@print";
}

or even shortened:

open FILE, "<", 'filename';
@lines = <FILE>;
if ($exists == 0){
 print "@lines[0 .. $#lines-5]";
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文