Bagaimana cara menerapkan filter ke output waktu nyata `tail -f`?

60
tail -f path

Di atas akan menampilkan modifikasi ke file secara instan, tetapi saya ingin menerapkan filter ke output, hanya ditampilkan ketika ada kata kunci xxxdi dalamnya.

Bagaimana cara mendekati ini?

wamp
sumber
1
Menandai jawaban sebagai diterima membantu orang lain yang membaca pertanyaan Anda dan jawaban mereka untuk mengetahui jawaban mana yang lebih mungkin membantu mereka jika mereka memiliki pertanyaan atau masalah yang serupa. Anda dapat mengunjungi kembali pertanyaan Anda sebelumnya dengan mengklik nama pengguna Anda.
Dennis Williamson

Jawaban:

84

Dengan Unix Anda dapat menyalurkan output dari satu program ke program lainnya.

Jadi untuk menyaring ekor, Anda dapat menggunakan grep:

tail -f path | grep your-search-filter
AddersUK
sumber
Tetapi katakanlah Anda memiliki 100 baris di bagian ekor (akhir file), dan baris ini adalah yang ingin Anda filter. Solusi Anda
TraderJoeChicago
1
Jika Anda hanya ingin mencari 100 baris terakhir file, coba tail -100 path | grep xxx
AddersUK
15

Jawaban singkat: tail -f somefile | grep somepattern

Namun, ini cenderung gagal. Katakanlah Anda mengekor file yang sering diputar (jika ini adalah log debug, mungkin diputar beberapa kali). Dalam hal ini tail -Fadalah temanmu. Saya akan membiarkan Anda mencari perbedaannya.

Tetapi tail -fdan tail -Fcetak banyak baris terlebih dahulu, yang sering kali tidak diinginkan dalam kasus penggunaan ini, jadi dalam kasus ini tambahkan-n0

tail -F -n0 somefile | grep somepattern

Itu akan baik-baik saja, sampai Anda ingin melakukan pemfilteran lain, dan kemudian Anda perlu waspada terhadap penyanggaan. stdout adalah buffer-line secara default saat menulis ke terminal tetapi ketika buffer-penuh saat menulis ke pipa. Jadi berikut ini akan memancarkan garis segera setelah mereka ditemukan, karena tailsecara garis-buffered (atau mem-flush output-nya di akhir setiap baris), dan grepjuga buffer-line karena outputnya pergi ke terminal Anda:

tail -F -n0 somefile | grep somepattern

Tetapi kemudian Anda memutuskan untuk menggunakan sesuatu seperti awkatau cutuntuk lebih lanjut memproses output.

tail -F -n0 somefile | grep somepattern | awk '{print $3}'

Dan sekarang Anda bertanya-tanya di mana output Anda telah pergi ... tergantung pada volume log, Anda mungkin menemukan bahwa Anda memang mendapatkan output, tetapi itu akan menjadi halaman sekaligus karena sekarang stdout grepberoperasi dengan mode buffered penuh, dan awkmenerima input 4kB sekaligus (secara default).

Dalam hal ini, Anda dapat mengatakan grepuntuk selalu membuat garis stdout di-buffer dengan menggunakan --line-bufferedopsi.

tail -F -n0 somefile | grep --line-buffered somepattern | ...

Namun, sebagian besar perintah tidak memiliki analog --line-buffered. Dalam hal alat yang lebih skrip, Anda dapat menggunakan fungsi untuk menyiram output (mis. Dalam awk, fungsinya adalah fflush(), yang memiliki nama yang sama dengan rekan C-nya, alat seperti Perl dan Python memiliki sesuatu yang serupa).

Dengan orang-orang seperti cutAnda kemungkinan kurang beruntung; ... tetapi Anda mungkin mencoba mencari unbuffer, yang saya pikir sesuatu disediakan oleh expecttoolchain (saya tidak pernah menggunakannya).

Saya harap Anda menemukan ini berguna.

Cheers, Cameron

Cameron Kerr
sumber
Saya sangat menghargai penjelasan mengapa ini bekerja dalam mode line-buffered. Itu wawasan yang luar biasa, terima kasih.
Hijau
2

dan Anda dapat menggunakan banyak pipa dan greps, dan mengecualikan hal-hal dengan grep -v, dapatkan case sensitif dengan grep -i, dll.

yaitu: tail -100f / var / log / messages | grep -V ACPI | grep -i ata

mulai tailing 100 baris dari akhir, dan tetap tailing, pertama-tama mengecualikan setiap garis dengan ACPI, kemudian tunjukkan garis dengan ata, ATA, atau campuran dari mereka.

Satu lagi yang berguna adalah opsi ABC, untuk baris Setelah, Sebelum, dan Konteks (baris sebelum dan sesudah).

Ronald Pottol
sumber