我希望能够查看自上次查询以来向文件添加了多少行,而无需再次读取整个文件。
就像是 :
ptail my_file | fgrep "[ERROR]" | wc -l
最好使用简单的 Perl 解决方案,因为我无法轻松访问编译器。
我希望能够查看自上次查询以来向文件添加了多少行,而无需再次读取整个文件。
就像是 :
ptail my_file | fgrep "[ERROR]" | wc -l
最好使用简单的 Perl 解决方案,因为我无法轻松访问编译器。
因为确实做到了,尽管它是在 C 中。
可能这个 Perl 包可以帮助你:
派生自 MultiTail,这个 perl 库可以很容易地使用完整的正则表达式跟踪文件的动态列表和匹配/排除行,甚至在本地维护它们的状态。
示例使用 File::Tail::Multi;
$tail1=File::Tail::Multi->new ( OutputPrefix => "f",
Debug => "$True",
Files => ["/var/adm/messages"]
);
while(1) {
$tail1->read;
#
$tail1->print;
sleep 10;
}
$tail1=File::Tail::Multi->new
: 创建新的 ptail 对象Files
=> 尾文件 /var/adm/messagesOutputPrefix
=> 在对象属性“LineArray”中每行的开头添加文件名$tail1->read
: 从文件中读取所有行$tail1->print
:打印对象属性“LineArray”中的所有行;尽管它出于其他目的消耗了这些行,但我之前已经编写了基本上这样做的代码。
您需要做的就是在尾部完成后记录每个文件的字节偏移量(使用tell)和 inode (使用stat)。下次针对文件运行时,首先再次检查 inode(使用stat)。如果 inode 已更改或文件小于记录的偏移量,则它是不同的文件(删除并重新创建,日志已旋转等),因此您应该从头开始显示;否则,寻找记录的偏移量并从那里显示它。
我实现了一个纯 Perl 版本的最小版本:
#! /usr/bin/perl
# Perl clone of since(1)
# http://welz.org.za/projects/since
#
use strict;
use warnings;
use Fcntl qw/ SEEK_SET O_RDWR O_CREAT /;
use NDBM_File;
my $state_file = "$ENV{HOME}/.psince";
my %states;
tie(%states, 'NDBM_File', $state_file, O_CREAT | O_RDWR, 0660)
or die("cannot tie state to $state_file : $!");
while (my $filename = shift) {
if (! -r $filename) {
# Ignore
next;
}
my @file_stats = stat($filename);
my $device = $file_stats[0];
my $inode = $file_stats[1];
my $size = $file_stats[7];
my $state_key = $device . "/" .$inode;
print STDERR "state_key=$state_key\n";
if (! open(FILE, $filename) ) {
print STDERR "cannot open $filename : $!";
next;
}
# Reverting to the last cursor position
my $offset = $states{$state_key} || 0;
if ($offset <= $size) {
sysseek(FILE, $offset, SEEK_SET);
} else {
# file was truncated, restarting from the beginning
$offset = 0;
}
# Reading until the end
my $buffer;
while ((my $read_count = sysread(FILE, $buffer, 4096)) > 0) {
$offset += $read_count;
print $buffer;
}
# Nothing to read
close(FILE);
$states{$state_key} = $offset;
}
# Sync the states
untie(%states);
@Dave:这几乎就像你的算法,除了我不使用tell,而是一个内部维护的计数器。