Apakah itu mungkin untuk digunakan grep
pada aliran berkelanjutan?
Yang saya maksud adalah semacam tail -f <file>
perintah, tetapi dengan grep
pada output untuk menjaga hanya garis yang menarik minat saya.
Saya sudah mencoba tail -f <file> | grep pattern
tetapi tampaknya grep
hanya bisa dieksekusi setelah tail
selesai, artinya tidak pernah.
tail -f file
bekerja (saya melihat output baru dalam waktu nyata)Jawaban:
Aktifkan
grep
mode line buffering saat menggunakan BSD grep (FreeBSD, Mac OS X dll.)Anda tidak perlu melakukan ini untuk GNU grep (digunakan pada hampir semua Linux) karena akan memerah secara default (YMMV untuk Unix-like lain seperti SmartOS, AIX atau QNX).
sumber
strace
. Tanpa--line-buffered
itu, itu tidak akan berhasil.tail -f | grep
, dan--line-buffered
menyelesaikannya untuk saya (di Ubuntu 14.04, GNU grep versi 2.16). Di mana logika "use line buffering if stdout is a tty" diterapkan? Di git.savannah.gnu.org/cgit/grep.git/tree/src/grep.c ,line_buffered
diset hanya oleh parser argumen.--line-buffered
saya tidak mendapatkan output. Namun, setelah pengujian, sepertinya GNU grep melakukan apa yang Anda gambarkan. Jadi seperti kebanyakan hal Unix, itu tergantung pada implementasi platform Anda. Karena pertanyaan tidak menentukan platform, informasi Anda tampaknya salah - setelah meninjau kode untuk BSD grep dan membandingkannya dengan GNU grep, perilaku tersebut pasti dikendalikan oleh opsi - line-buffered. Hanya saja grep GNU memerah secara default.Saya menggunakan
tail -f <file> | grep <pattern>
semua waktu.Ini akan menunggu sampai grep memerah, tidak sampai selesai (saya menggunakan Ubuntu).
sumber
Saya pikir masalah Anda adalah bahwa grep menggunakan beberapa buffering output. Mencoba
itu akan mengatur mode buffering output grep ke unbuffered.
sumber
grep
.unbuffer
(dalamexpect-dev
paket pada debian) adalah raja . Jadi saya akan menggunakan unbuffer di atas stdbuf.top
dengan stdbuf dan unbuffer). Dan benar-benar tidak ada solusi 'ajaib': unbuffer kadang-kadang gagal juga, misalnya awk menggunakan implementasi buffer yang berbeda (stdbuf juga akan gagal).stdbuf
, `unbuffer, dan stdio buffering di pixelbeat.org/programming/stdio_bufferingJika Anda ingin menemukan kecocokan di seluruh file (bukan hanya ekor), dan Anda ingin itu cocok dan menunggu kecocokan baru, ini berfungsi dengan baik:
The
-c +0
flag mengatakan bahwa output harus mulai0
byte (-c
) dari awal (+
) dari file.sumber
Dalam kebanyakan kasus, Anda bisa
tail -f /var/log/some.log |grep foo
dan itu akan berfungsi dengan baik.Jika Anda perlu menggunakan banyak greps pada file log yang sedang berjalan dan Anda menemukan bahwa Anda tidak mendapatkan output, Anda mungkin perlu menempelkan
--line-buffered
sakelar ke grep tengah Anda , seperti:sumber
Anda dapat menganggap jawaban ini sebagai peningkatan .. biasanya saya gunakan
-F lebih baik jika file diputar (-f tidak akan berfungsi dengan baik jika file diputar)
-A dan -B berguna untuk mendapatkan garis sebelum dan sesudah terjadinya pola .. blok ini akan muncul di antara pemisah garis putus-putus
Tetapi bagi saya, saya lebih suka melakukan yang berikut
ini sangat berguna jika Anda ingin mencari di dalam log yang dialirkan. Maksud saya kembali dan maju dan melihat secara mendalam
sumber
grep -C 3 <pattern>
, ganti -A <N> dan -B <N> jika N sama.Tidak melihat siapa pun menawarkan kunjungan biasa untuk ini:
Saya lebih suka ini, karena Anda dapat menggunakan
ctrl + c
untuk berhenti dan menavigasi file kapan saja, dan kemudian tekan sajashift + f
untuk kembali ke pencarian streaming langsung.sumber
sed akan menjadi pilihan yang lebih baik ( editor aliran )
tail -n0 -f <file> | sed -n '/search string/p'
dan kemudian jika Anda ingin perintah ekor keluar setelah Anda menemukan string tertentu:
tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'
Jelas bashism: $ BASHPID akan menjadi id proses dari perintah tail. Perintah sed adalah setelah tail di pipa, jadi id proses sed akan menjadi $ BASHPID + 1.
sumber
$BASHPID+1
) akan menjadi milik Anda adalah salah dalam banyak situasi, dan ini tidak melakukan apa pun untuk menyelesaikan masalah buffering yang mungkin merupakan pertanyaan yang ingin ditanyakan OP. Secara khusus, merekomendasikansed
digrep
sini sepertinya hanya masalah preferensi (meragukan). (Anda bisa mendapatkanp;q
perilakugrep -m 1
jika itu yang ingin Anda sampaikan.)--line-buffered
tidak. Saya dengan tulus tidak mengerti angka minus 1.Ya, ini sebenarnya akan bekerja dengan baik.
Grep
dan sebagian besar perintah Unix beroperasi pada stream satu baris pada satu waktu. Setiap baris yang keluar dari ekor akan dianalisis dan diteruskan jika cocok.sumber
grep
adalah perintah terakhir dalam rantai pipa, itu akan bertindak seperti yang Anda jelaskan. Namun, jika itu di tengah itu akan buffer sekitar 8k output sekaligus.Perintah yang satu ini bekerja untuk saya (Suse):
mengumpulkan login ke layanan surat
sumber
Anda tentu tidak akan berhasil
ketika Anda menggunakan "colortail" sebagai alias untuk ekor, mis. di bash
Anda dapat memeriksa berdasarkan jenis alias jika ini menghasilkan sesuatu seperti alias ekor isan
colortail -n 30
. maka Anda memiliki pelakunya :)Larutan:
hapus alias dengan
pastikan Anda menggunakan biner ekor 'asli' dengan perintah ini
yang akan menghasilkan sesuatu seperti:
dan kemudian Anda dapat menjalankan perintah Anda
Semoga berhasil.
sumber
Gunakan awk (utilitas bash hebat lainnya) alih-alih grep di mana Anda tidak memiliki opsi buffered baris! Ini akan terus mengalirkan data Anda dari ekor.
ini adalah bagaimana kamu menggunakan grep
Ini adalah bagaimana Anda akan menggunakan awk
sumber
{print $0}
ini mubazir, karena pencetakan adalah tindakan default ketika suatu kondisi lewat.)