ekor file log tetapi hanya tampilkan baris tertentu

29

Saya tailing file log dengan flag -f. Lalu saya memipiskan ini ke grep, untuk menemukan hanya garis yang berisi "X". Itu bekerja dengan sangat baik. Sekarang saya ingin pipa ini lagi ke grep lain, yang akan menghapus semua baris yang mengandung "Y". Ketika saya menambahkan pipa kedua, file berhenti menyegarkan dan sepertinya tidak ada data yang datang.

Ini adalah perintah yang berfungsi: tail -f my_file.log | grep "X"

Ini adalah perintah yang tidak: tail -f my_file.log | grep "X" | grep -v "Y"

Bagaimana saya harus menyusun ini sehingga perintah itu berfungsi?

Ori Horev
sumber
1
coba lakukan satu pipa dengan satu pipa, ubah urutannya, lakukan tail -f file|grep -v "Y". jika outputnya ok maka lanjutkan untuk menambahkan grep "X".
Aizuddin Zali

Jawaban:

38

Karena output dari grepbuffered, gunakan --line-bufferedopsi grepuntuk mengaktifkan line buffering:

tail -f /path/to/log | grep --line-buffered 'X' | grep -v 'Y'

Jika Anda greptidak memiliki opsi, Anda dapat menggunakan stdbufsebagai alternatif:

tail -f /path/to/log | stdbuf -oL grep 'X' | grep -v 'Y'
heemayl
sumber
1
Saya bertanya-tanya bagaimana cara stdbufmemberitahu libstdbuf.sopengaturan mana yang digunakan.
kasperd
@kasperd: Variabel lingkungan.
Nate Eldredge
1
@NateEldredge Saya sudah mencari variabel lingkungan di output dari diff -u <(env) <(stdbuf env)dan tidak menemukannya. Tetapi sekarang saya menyadari bahwa apa yang seharusnya saya uji adalah diff -u <(env) <(stdbuf -oL env).
kasperd
Saya juga jenis masalah yang sama. kasus saya adalah, saya perlu mencetak semua baris yang mengandung 'aaa' dan 'bbb'. Solusi pertama di atas tidak berfungsi. Solusi kedua adalah bekerja untuk 'aaa' ada dan 'bbb' tidak ada. keduanya ada tidak berfungsi. tidak memberikan hasil. perintah saya terlihat seperti ini: tail -f test.txt | stdbuf -oL grep 'aaa' | grep 'bbb' tidak memberikan output apa pun. Bisakah bantu saya.
Minggu
18

Saya biasanya merasa lebih berguna awkuntuk pemeriksaan logis semacam ini:

tail -f /path/to/log | awk '/X/ && !/Y/'
#                           ^^^    ^^^^
#                   this I want    but not this

Diuji dengan memiliki dua tab, satu di mana saya terus menulis seq 20 >> myfiledan yang lainnya misalnya tail -f myfile | awk '/3/ && !/13/'.

fedorqui
sumber
15

Pendekatan lain adalah menggunakan grepdoa tunggal alih-alih dua dan karenanya menghindari masalah buffering. Cukup gunakan ekspresi reguler yang cocok dengan garis yang terdiri dari 0 atau lebih karakter non-Y, lalu X dan kemudian 0 atau lebih non-Ys lagi hingga akhir baris "

tail -f /path/to/log | grep '^[^Y]*X[^Y]*$'
terdon
sumber