Menulis output "tail -f" ke file lain

34

Sebagai kelanjutan dari posting terakhir saya di mana saya biasa grep & tail -fmenemukan kejadian "langka". Saya ingin merekam ini di file lain.

Saya sudah mencoba berputar

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

ke

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

File dibuat, tetapi tidak ada yang terisi, apakah ini masalah caching atau sebaliknya? Bagaimana saya bisa menambahkan keluaran ekor saya secara real-time ke file baru?

Mike
sumber

Jawaban:

44

Buffer adalah masalahnya.

Lakukan dengan cara ini,

tail -f log.txt | egrep --line-buffered 'WARN | ERROR' | | tee filtered_output.txt
# ^^^^^^^^^^^^^^^

Dikonfirmasi untuk mengerjakan Cygwin juga.

nik
sumber
6

Ini mungkin masalah buffering. Lihat posting SO ini tentang menonaktifkan buffer otomatis saat menggunakan pipa . Anda dapat menggunakan unbufferperintah dari expect:

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

Sunting : Karena Anda memiliki saluran pipa yang lebih panjang, Anda mungkin perlu membatalkan pembuatan setiap perintah (kecuali yang terakhir):

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

Sunting 2 : unbuffertersedia di Cygwin dari expectpaket sumber (mis. Harapkan-20030128-1-src.tar.bz2 , ditemukan di expect/examplesfolder), tetapi ini skrip yang sangat pendek. Jika Anda expectsudah menginstal paket, cukup masukkan ini ke dalam skrip bernama unbufferdi /usr/local/bindirektori Anda :

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

eval spawn -noecho $argv
set timeout -1
expect

Pada Debian, unbufferperintah disediakan dalam expect-devpaket dan diinstal sebagai expect_unbuffer.

quack quixote
sumber
apakah ada cara untuk mencapai ini dengan cygwin?
Mike
menambahkan info tentang penggunaan di cygwin; Anda akan membutuhkan expectpaket.
Quack quixote
Terima kasih, tidak dapat mencoba sampai Senin sekarang dengan sedih. Akan diperbarui kemudian.
Mike
4

Ketika menggunakan perintah yang tidak benar-benar 'selesai' (seperti tail -f), ini sebenarnya tidak benar-benar berfungsi atau sama sekali (sama sekali).

Anda harus dapat mengarahkan output ke file teks. Coba ini:

tail -f log.txt | egrep 'WARN|ERROR' > filtered_output.txt
Josh Hunt
sumber
1
Ini sepertinya tidak berhasil.
Mike
2

Ini adalah versi unbufferyang saya miliki:

#!/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
}
Dijeda sampai pemberitahuan lebih lanjut.
sumber
+1 terima kasih atas info tambahannya. tidak tahu apakah itu ramah cygwin tetapi sepertinya skrip yang lebih cerdas.
Quack quixote
2

Seperti yang telah ditunjukkan orang lain, Anda dapat menggunakan unbufferutilitas dari Expect.

Namun, perlu diketahui bahwa tergantung pada sistem Anda dan versi Expect yang tersedia, Anda mungkin perlu menggunakan -pperalihan untuk tidak membangun buffer. Mengutip halaman manual:

   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

Jadi Anda mungkin perlu doa ini:

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

BTW, lihat artikel ini untuk penjelasan menyeluruh tentang masalah buffering output: http://www.pixelbeat.org/programming/stdio_buffering/

Aleksander Adamowski
sumber