2008-10-29 35 views
5

Tôi muốn có thể xem có bao nhiêu dòng được thêm vào một tệp kể từ lần quering cuối cùng mà không đọc toàn bộ tệp một lần nữa.Đuôi trạng thái (chỉ hiển thị các dòng mới từ lần thực hiện cuối cùng)

Cái gì như:

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

Một giải pháp đơn giản trong Perl sẽ được ưa thích, vì tôi không có quyền truy cập dễ dàng để một trình biên dịch.

Trả lời

2

Mặc dù nó đã tiêu thụ các dòng cho các mục đích khác, nhưng tôi đã viết mã về bản chất trước đây.

Tất cả bạn cần làm là ghi lại các byte offset (với nói) và inode (với stat) cho mỗi tập tin sau đuôi hoàn tất. Lần sau nó chạy với tập tin, trước tiên hãy kiểm tra inode (với stat) một lần nữa. Nếu inode đã thay đổi hoặc tập tin nhỏ hơn so với offset được ghi lại, thì đó là một tệp khác (đã xóa và tạo lại, nhật ký đã được xoay, vv), vì vậy bạn nên hiển thị nó ngay từ đầu; nếu không, hãy tìm kiếm đến độ lệch được ghi và hiển thị nó từ đó.

2

since không chính xác điều đó mặc dù nó là trong C.

+0

Bạn có thể vừa chỉnh sửa câu hỏi của mình. – Axeman

2

Có thể gói Perl này có thể giúp bạn:

File::Tail::Multi

Xuất phát từ multitail, thư viện perl này làm cho nó dễ dàng để một cái đuôi động danh sách các tệp và kết hợp/ngoại trừ các dòng sử dụng các biểu thức chính quy đầy đủ và thậm chí duy trì trạng thái của chúng cục bộ.

VÍ DỤ sử dụng Tệp :: đuôi :: Đa;

$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: Tạo đối tượng ptail mới
  • Files => tập tin Tail/var/adm/messages
  • OutputPrefix => Thêm vào trước tên của tập tin đầu mỗi dòng trong thuộc tính đối tượng "LineArray "
  • $tail1->read: Đọc tất cả các dòng từ các tệp
  • $tail1->print: In tất cả các dòng trong thuộc tính đối tượng" LineArray ";
+0

Đó là * nhận * là câu trả lời perl! – Axeman

+0

Ở đây trạng thái được duy trì, nhưng chỉ trong một lần thực hiện chương trình. Tôi muốn trạng thái được lưu qua các lần thực hiện chương trình. –

2

tôi thực hiện một phiên bản tối thiểu của một phiên bản Perl tinh khiết:

#! /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: Nó gần giống như thuật toán của bạn, ngoại trừ việc tôi không sử dụng nói, nhưng một quầy duy trì nội bộ.

Các vấn đề liên quan