Viết đuôi đuôi -f xuất ra tệp khác


34

Như một sự tiếp nối từ bài đăng cuối cùng của tôi , nơi tôi đã sử dụng grep & tail -fđể tìm sự xuất hiện của các sự kiện "hiếm". Tôi muốn ghi lại điều này trong một tập tin khác.

Tôi đã thử rẽ

tail -f log.txt | egrep 'WARN|ERROR'

vào

tail -f log.txt | egrep 'WARN|ERROR' | tee filtered_output.txt

Các tập tin được tạo ra, nhưng không có gì được điền, đây có phải là một vấn đề bộ đệm hay không? Làm cách nào tôi có thể nối thêm thời gian thực của đầu ra đuôi của mình vào một tệp mới?

Câu trả lời:


44

Đệm là vấn đề.

Làm như thế này,

đuôi -f log.txt | egrep - đệm-line 'WARN | ERROR' | tee đã lọc
# ^ ^ ^ ^ ^ ^ ^ ^ ^ ^

Xác nhận làm việc trên Cygwin quá.


6

Đây có lẽ là một vấn đề đệm. Xem bài đăng SO này về việc vô hiệu hóa bộ đệm tự động khi sử dụng đường ống . Bạn có thể sử dụng unbufferlệnh từ expect:

$ unbuffer tail -f log.txt | egrep 'WARN|ERROR' | tee filtered_output.txt

Chỉnh sửa : Vì bạn có một đường ống dài hơn, nên có thể bạn cần hủy kết nối từng lệnh (ngoại trừ lệnh cuối cùng):

$ unbuffer tail -f log.txt | unbuffer egrep 'WARN|ERROR' | tee filtered_output.txt

Chỉnh sửa 2 : unbuffercó sẵn trên Cygwin từ expectgói nguồn (ví dụ: mong đợi-20030128-1-src.tar.bz2 , được tìm thấy trong expect/examplesthư mục), nhưng đó là một đoạn mã rất ngắn. Nếu bạn expectđã cài đặt gói, chỉ cần đặt gói này vào tập lệnh được gọi unbuffertrong /usr/local/binthư mục của bạn :

#!/usr/bin/expect --
# Description: unbuffer stdout of a program
# Author: Don Libes, NIST

eval spawn -noecho $argv
set timeout -1
expect

Trên Debian, unbufferlệnh được cung cấp trong expect-devgói và được cài đặt dưới dạng expect_unbuffer.


Có cách nào để thực hiện điều này với cygwin?
Mike

thêm thông tin về việc sử dụng trong cygwin; bạn sẽ cần expectgói.
quack quixote

Cảm ơn, không thể cố gắng cho đến thứ Hai bây giờ thật đáng buồn. Sẽ cập nhật rồi.
Mike

4

Khi sử dụng một lệnh không thực sự 'kết thúc' (chẳng hạn như tail -f), điều này thực sự không thực sự hiệu quả hoặc tốt (tất cả).

Bạn sẽ có thể chuyển hướng đầu ra thành một tệp văn bản. Thử đi:

tail -f log.txt | egrep 'WARN|ERROR' > filtered_output.txt

1
Điều này dường như không hoạt động.
Mike

2

Đây là phiên bản unbuffermà tôi có:

#!/usr/bin/expect --
# Description: unbuffer stdout of a program
# Author: Don Libes, NIST

if {[string compare [lindex $argv 0] "-p"] == 0} {
    # pipeline
    set stty_init "-echo"
    eval spawn -noecho [lrange $argv 1 end]
    close_on_eof -i $user_spawn_id 0
    interact {
    eof {
        # flush remaining output from child
        expect -timeout 1 -re .+
        return
    }
    }
} else {
    set stty_init "-opost"
    set timeout -1
    eval spawn -noecho $argv
    expect
}

+1 cảm ơn về thông tin bổ sung. dunno nếu nó thân thiện với cygwin nhưng có vẻ như một kịch bản thông minh hơn.
quack quixote

2

Như những người khác đã chỉ ra, bạn có thể sử dụng unbuffertiện ích từ Expect.

Tuy nhiên, lưu ý rằng tùy thuộc vào hệ thống và phiên bản Mong đợi có sẵn của bạn, bạn có thể cần phải sử dụng công -ptắc để giải nén. Trích dẫn trang người đàn ông:

   Normally, unbuffer does not read from stdin.  This simplifies use of unbuffer in some situations.  To use unbuffer in a  pipeline,  use
   the -p flag.  Example:

           process1 | unbuffer -p process2 | process3

Vì vậy, bạn có thể cần lời mời này:

unbuffer -p tail -f log.txt | unbuffer -p egrep 'WARN|ERROR' | tee filtered_output.txt

BTW, xem bài viết này để được giải thích kỹ lưỡng về vấn đề đệm đầu ra: http://www.pixelbeat.org/programming/stdio_buffering/

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.