有状态尾部(仅显示上次执行的新行)

发布于 2024-07-07 22:39:57 字数 168 浏览 7 评论 0原文

我希望能够查看自上次查询以来向文件添加了多少行,而无需再次读取整个文件。

像这样的东西:

ptail my_file | fgrep "[ERROR]" | wc -l 

最好使用简单的 Perl 解决方案,因为我无法轻松访问编译器。

I want to be able to see how many lines were added to a file since the last quering without reading the whole file again.

Something like :

ptail my_file | fgrep "[ERROR]" | wc -l 

A solution in simple Perl would be prefered, since I don't have an easy access to a compiler.

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

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

发布评论

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

评论(4

离鸿 2024-07-14 22:39:57

尽管它消耗了这些线路用于其他目的,但我之前已经编写过基本上执行此操作的代码。

您需要做的就是在尾部完成后记录每个文件的字节偏移量(使用 tell)和索引节点(使用 stat)。 下次对文件运行时,首先再次检查 inode(使用 stat)。 如果 inode 已更改或文件小于记录的偏移量,则它是一个不同的文件(已删除并重新创建、日志已旋转等),因此您应该从头开始显示它; 否则,寻找记录的偏移量并从那里显示它。

Although it consumed the lines for other purposes, I have written code which does essentially this before.

All you need to do is record the byte offset (with tell) and inode (with stat) for each file after the tail is complete. The next time it's run against the file, first check the inode (with stat) again. If the inode has changed or the file is smaller than the recorded offset, then it's a different file (deleted and recreated, log got rotated, etc.), so you should show it from the beginning; otherwise, seek to the recorded offset and display it from there.

审判长 2024-07-14 22:39:57

since 确实做到了这一点,尽管它是用 C 语言编写的。

since does exactly that although it is in C.

五里雾 2024-07-14 22:39:57

也许这个 Perl 包可以帮助你:

File::Tail::Multi

这个 Perl 库源自 MultiTail,可以轻松使用完整的正则表达式跟踪动态文件列表和匹配/排除行,甚至可以在本地维护它们的状态。

示例使用 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/messages
  • OutputPrefix => 在对象属性“LineArray”中的每行开头添加文件名
  • $tail1->read :从文件中读取所有行
  • $tail1->print :打印对象属性“LineArray”中的所有线;

May be this Perl package can help you:

File::Tail::Multi

Derived from MultiTail, this perl library makes it easy to tail a dynamic list of files and match/except lines using full regular expressions and even maintains their state locally.

EXAMPLE use 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 : Create new ptail object
  • Files => Tail file /var/adm/messages
  • OutputPrefix => Prepend the name of the file beginning of each line in object attribute "LineArray"
  • $tail1->read : Read all line from files
  • $tail1->print : Print all line in object attribute "LineArray";
浅黛梨妆こ 2024-07-14 22:39:57

我实现了纯 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,而是使用内部维护的计数器。

I implemented a minimal version of a pure Perl version :

#! /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: It's almost like your algorithm, except that i don't use tell, but an internal maintained counter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文