如何逆序一行一行的输出文件?

如何逆序一行一行的输出文件?

假如说有一个log文件,会不断有记录写入会变得很大,有一个cron每1个小时读一次这个文件的倒数20行看看有没有特殊错误出现。
应该怎么做?

open(FILE ,"D:\\hello.txt") || die "open filed" ;

print reverse <FILE>;

这样子倒是可以逆序打出,可是不能分行控制只读取20行啊

而且感觉这样做也是把这个文件一行一行读出来然后放到一个数组然后倒序的 那样文件很大的话内存会崩掉的吧

用seek?用read?可是要一行一行的读,而且每一行的长度又不固定

怎么办呢?
就是 seek 加 read
或者你可以 Tie::File
use File::Tail;

http://search.cpan.org/~mgrabnar/File-Tail-0.99.3/Tail.pm



QUOTE:
原帖由 sdlxf 于 2007-12-3 16:52 发表
假如说有一个log文件,会不断有记录写入会变得很大,有一个cron每1个小时读一次这个文件的倒数20行看看有没有特殊错误出现。
应该怎么做?

open(FILE ,"D:\\hello.txt" || die "open filed" ;

print re ...



[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/perl
# reverse.plx
use warnings;
use strict;
my $input = shift;
my $output = shift;
open INPUT, $input or die "Couldn't open file $input: $!\n";
open OUTPUT, ">$output" or die "Couldn't open file $input: $!\n";
my @file = <INPUT>;
@file = reverse @file;
#print OUTPUT @file;
foreach my $i ( 1..3 ) {
        print OUTPUT $file[$i];
}

放到数组应该不会崩掉吧?
因为书上也有 @file = <>;
当然如果是为了太多,可以存到数组的只是我们需要的,最后几行吧.

不过还请有人介绍下<>把大文件所有内容放到数组,会不会有问题


QUOTE:
原帖由 放驴娃 于 2007-12-3 17:18 发表
就是 seek 加 read
或者你可以 Tie::File

seek 加 read 还是不知道怎么做…… seek 除了文件句柄外有两个参数,第一个是位置,第二个是表示从什么地方开始seek(起始位置,当前位置,文件结束位置) 对吗?
可是不知道文件最后一行有多长啊 文件每一行的size都是不固定的

Tie::File 是把文件的每一行都映射到对应数组的元素中,但并非是文件内容存放在数组中是吗?

谢谢了!!!


QUOTE:
原帖由 Lonki 于 2007-12-3 17:21 发表
use File::Tail;

http://search.cpan.org/~mgrabnar/File-Tail-0.99.3/Tail.pm

谢谢了!!!正在拜读中…… 英语不大好,呵呵 有几个参数的使用再看看


QUOTE:
原帖由 lonelyair 于 2007-12-4 13:59 发表


放到数组应该不会崩掉吧?
因为书上也有 @file = <>;
当然如果是为了太多,可以存到数组的只是我们需要的,最后几行吧.   

不过还请有人介绍下<>把大文件所有内容放到数组,会不会有问题

数组应该是在内存中的吧,log文件一般都会很大,假如好几个G的文件存到数组中 担心内存使用量啊!

等有人给介绍下会不会有问题吧……
Windows上, Perl的数组占用内存大概是实际大小的6-7倍左右.
例如: 50M的文件, 一次读入数组会占用mem+vm在300M-350M左右.
1G内存, 一次读入400M的文件再处理, 机器就会长时间失去响应.
通常LOG文件通常都巨大无比, 不要去折磨服务器.

性能上, 读几M至几十M的文件, my @lines = <FH>都比while (my $line = <FH>)的处理方式慢不少:<
所以, 如果不是特殊需要, 逐行读取是最佳方式.


Perl有相应的tail module, 参见3楼.
至于Linux的tail的实现, 可以去看看gnu text utils


QUOTE:
原帖由 Lonki 于 2007-12-4 15:31 发表
Windows上, Perl的数组占用内存大概是实际大小的6-7倍左右.
例如: 50M的文件, 一次读入数组会占用mem+vm在300M-350M左右.
1G内存, 一次读入400M的文件再处理, 机器就会长时间失去响应.
通常LOG文件通常都巨大 ...

谢谢~! 好好去啃FILE::Tail……
或许是我代码不对?从cpan上的例子抄下来

[Copy to clipboard] [ - ]
CODE:
use File::Tail;
$file=File::Tail->new("D:\\hello.txt");
while (defined($line=$file->read)) {
  print "$line";
}

一执行cpu占用就90%左右,而且没反应,没有数据打印出来 是怎么回事啊?
默认值是10秒检查一次, 没有新数据时会block.
运行你的perl script之后, 往D:\\Hello.txt的末尾加入新行,
比如echo 12345 >> D:\\Hello.txt, 就能看到输出.

CPU占用情况我暂时无法测, 不清楚.