5

ファイル全体を再度読み取ることなく、最後のクエリ以降にファイルに追加された行数を確認できるようにしたいと思います。

何かのようなもの :

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

コンパイラに簡単にアクセスできないので、単純なPerlのソリューションが好まれます。

4

4 に答える 4

2

それはCにありますが、まさにそれを行います。

于 2008-10-29T20:30:59.870 に答える
2

この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/messages
  • OutputPrefix=>オブジェクト属性「LineArray」の各行の先頭にファイルの名前を追加します
  • $tail1->read: ファイルからすべての行を読み取ります
  • $tail1->print: オブジェクト属性「LineArray」のすべての行を出力します。
于 2008-10-29T20:55:10.023 に答える
2

他の目的で行を消費しましたが、本質的にこれを行うコードを以前に書きました。

テールが完成した後、各ファイルのバイト オフセット ( tell を使用) と inode ( statを使用) を記録するだけです。次にファイルに対して実行するときは、最初に inode を ( statを使用して) 再度チェックします。inode が変更された場合、またはファイルが記録されたオフセットよりも小さい場合、それは別のファイル (削除されて再作成された、ログがローテーションされたなど) であるため、最初から表示する必要があります。それ以外の場合は、記録されたオフセットを探して、そこから表示します。

于 2008-10-29T23:50:02.340 に答える
2

純粋な 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 を使用しないことを除いて、アルゴリズムとほとんど同じです、内部で維持されるカウンターです。

于 2008-10-30T13:18:04.143 に答える