tail -f, tetapi dengan nomor garis

21

Saya mencoba untuk melihat berapa kali foo barmuncul /var/log/foo.logdalam jumlah waktu yang sewenang-wenang pada server jauh, tetapi tidak ada yang saya coba sejauh ini yang berhasil.

Saya sudah punya skrip pengatur waktu yang saya gunakan untuk melacak berapa lama sejak saya mulai membuntuti /var/log/foo.log, dan sekarang saya hanya ingin cara untuk mengetahui berapa kali foo bartelah muncul di keluaran berekor.

Saya mencari di Google, tetapi saya tidak menemukan sesuatu yang relevan dalam 10 halaman pertama hasil.

Inilah yang saya coba dengan hasil yang membuat frustrasi:

## works on local machine, but doesn't work as expected on remote
tail -f /var/log/foo.log | grep foo\ bar | sed '='

## works on local, but not remote
tail -f /var/log/foo.log | grep foo\ bar | cat -n -

##  works on local, but not remote
tail -f /var/log/foo.log | grep foo\ bar | awk -F'\n' '{printf "[%d]> ", NR; print $1}'

Saya bahkan mencoba untuk menulis skrip sed yang akan bertindak seperti tail -f, tapi saya membuat kemajuan tanpa batas dengan itu.

CATATAN

server jarak jauh menjalankan versi coreutils yang lebih lama, dan memutakhirkan adalah suatu pilihan, tetapi TIDAK dengan cara apa pun solusi yang diinginkan.

Alexej Magura
sumber
2
Dengan cara apa itu tidak berhasil? Coba --line-bufferedopsi untuk grep. Atautail -f ... | awk '/foo bar/{print ++n, $0}'
Stéphane Chazelas
Mengapa itu tidak berfungsi di remote? Contoh:tail -f /var/log/log.log | awk '{ printf "[%d]> %s\n", NR+1 ,$0; fflush(stdout); }'

Jawaban:

29
tail -f | nl

berfungsi untuk saya dan ini adalah yang pertama saya pikirkan - yaitu jika Anda benar-benar ingin garis-garisnya bernomor 1 dan bukan dengan nomor garis nyata dari berkas yang ditonton. Secara opsional tambahkan grepjika diperlukan ke tempat yang sesuai (baik sebelum atau sesudah nl). Namun, ingatlah bahwa buffering dapat terjadi. Dalam kasus khusus saya, grepmemiliki --line-bufferedopsi, tetapi nlbuffer output dan tidak memiliki opsi untuk mematikannya. Karenanya tail | nl | grepkombo tidak benar-benar mengalir dengan baik.

Yang mengatakan,

tail -f | grep -n pattern

bekerja untuk saya juga. Penomoran dimulai lagi dari awal "tailing" daripada awal seluruh file log.

peterph
sumber
versi grep yang berjalan di server tidak memiliki -nopsi.
Alexej Magura
Namun, ia memiliki opsi panjang --line-number: tail -f /var/log/foo.log | grep foo\ bar --line-numberberfungsi!
Alexej Magura
1
Itu menarik - saya belum memeriksa POSIX seperti itu, tetapi manual GNU grep mengatakan: -n ditentukan oleh POSIX .
peterph
16

Saya pikir ini lebih baik ..

less -N +F <filepath>
Adam Eberlin
sumber
2
Bisakah Anda menjelaskan mengapa menurut Anda lebih baik?
Navigatron
Ini suntingan besar, saya kembali.
Adam Eberlin
3
Memperlihatkan pengambilan nomor baris sebagai referensi seluruh file. tail -f | nl menunjukkan pengambilan nomor baris sebagai referensi keluaran pertama ekor.
rafaelvalle
Ini sangat berguna dan membahas Judul OP tetapi bukan pertanyaan mereka . Mereka ingin tahu berapa kali X muncul dalam file: P
Timmah
6

Anda juga dapat menyalurkan output ke less, ia memiliki fitur nomor baris, -Nyang akan memungkinkan Anda untuk menggulir bolak-balik melalui log.

$ tail -f /var/log/foo.log | less -N

Contoh

  1 Jan 17 22:11:58 greeneggs fprintd[4323]: ** Message: entering main loop
  2 Jan 17 22:12:01 greeneggs su: (to root) saml on pts/5
  3 Jan 17 22:12:28 greeneggs fprintd[4323]: ** Message: No devices in use, exit
  4 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Git | personal_repo | Checking for remote changes...
  5 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Cmd | personal_repo | git rev-parse HEAD
  6 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Cmd | personal_repo | git ls-remote --heads --exit-code "ssh://[email protected]      
  6 8us.org/home/sam/SparkleShare/personal_repo.git" master
  7 Jan 17 22:12:58 greeneggs gnome-session[1876]: X11 forwarding request failed on channel 1
  8 Jan 17 22:12:58 greeneggs gnome-session[1876]: 22:12:58 | Git | personal_repo | No remote changes, local+remote: 532213be48cce3b93cb177d409faa      
  8 03b71d0cfa5
  9 Jan 17 22:13:35 greeneggs gnome-session[1876]: 22:13:35 | ListenerTcp | Pinging tcp://notifications.sparkleshare.org:443/
 10 Jan 17 22:13:35 greeneggs gnome-session[1876]: 22:13:35 | ListenerTcp | Received pong from tcp://notifications.sparkleshare.org:443/

CATATAN: Perhatikan output. Anda mungkin atau mungkin tidak suka fitur ini, tetapi akan mengambil garis panjang dan memotongnya sehingga mereka melanjutkan pada baris berikutnya, tetapi masih mempertahankan nomor baris yang sesuai. Saya menemukan fitur ini sangat berharga ketika mem-parsing file log yang lebar! Anda dapat melihat efek dari fitur ini pada baris 6 & 8 .

slm
sumber
Ini tidak jelas. Di mana nama file ditentukan? Ini harus diklarifikasi, mencatat bahwa output dinomori dari 1 dimulai dengan 10 baris terakhir dari nama file, karena itu adalah perilaku default tail. Adapun garis panjang, perilaku itu diaktifkan dalam lessmenggunakan -S.
ILMostro_7
2

Untuk menerima baris baru hanya di file log saat mereka datang dengan nomor baris mereka, Anda bisa melakukan:

{
  initial_lines=$(wc -l)
  tail -n +1 -f | awk -v NR="$initial_lines" '/pattern/{print NR": "$0}'
} < file.log

(dengan mawk, Anda ingin menambahkan -Winteractiveopsi untuk mencegah buffering input (!)).

wc -lmembaca baris yang sudah ada dan menghitungnya (karakter baris baru yang artinya masih berfungsi bahkan jika baris terakhir belum penuh), dan kemudian kita tail -fsisanya (mulai dari tempat wcberhenti membaca) dan memberi tahu awkberapa nomor baris dari yang pertama dilihatnya.

Stéphane Chazelas
sumber
memilih lsebagai nama variabel membuat saya memicingkan mata pada $ l, berpikir itu $1^^ (tapi seperti yang saya tahu (dan kepercayaan 100%) Anda, saya membaca ulang dan melihat kebenaran). Hanya untuk rasa ingin tahu: untuk menghindari beberapa "kondisi ras" antara wc -ldan tail -f(jika file tumbuh cepat, seseorang dapat membuang beberapa baris dan dengan demikian NR dimulai dari angka yang salah), apakah mungkin untuk melewati $lgaris saja? (dan batas apa yang ada untuk -nmengekor di posix & di gnu?). Mungkin dengan file perantara sementara?
Olivier Dulac
@OlivierDulac, tail -n +1(baca apa pun dari posisi awal) mengatasi masalah kondisi lomba. Ini akan membaca baris yang tidak ada dalam file pada saat wc -ldiakhiri, dari posisi yang tepat wcmeninggalkannya. Jadi NR akan memiliki posisi yang tepat terlepas dari berapa banyak baris yang telah ditulis di antara wcakhir dan tailawal. Itu jika Anda diberitahu tailuntuk memulai dari beberapa posisi relatif ke akhir file yang Anda akan memiliki masalah.
Stéphane Chazelas
oh, interresting: memang, data menumpuk menjadi stdin sementara tidak ada yang membacanya (antara akhir wc sampai awal kepala) ... saya harus menyadari itu. Terima kasih. Sekarang saya mengerti mengapa Anda "<mengajukan". pintar, seperti biasa :)
Olivier Dulac
1
@OlivierDulac, tentang batasan (yang tidak berlaku di tail -n +1sini), untuk file biasa, sebagian besar implementasi tidak memiliki satu karena mereka dapat mulai dari akhir dan seekkembali sampai mereka menemukan baris baru ke-n tanpa harus menyimpan lebih dari satu nilai buf data dalam memori. Untuk input yang tidak dapat dicari, di situlah Anda dapat mengalami batasan. POSIX membutuhkan implementasi untuk dapat menyimpan setidaknya 10 x LINE_MAX byte (LINE_MAX setidaknya 2048). GNU tail tidak memiliki batas selain memori AFAIK
Stéphane Chazelas
0

Jika Anda ingin memberi nomor dari awal, Anda perlu grep -n untuk diterapkan ke semua baris.

 tail -f -n100000000 filename.log | grep -n '' 

Jika Anda hanya ingin menunjukkan 10 yang terakhir, saya pikir Anda dapat mengekor kembali file tersebut:

 tail -f -n100000000 filename.log | grep -n '' | tail -n10

Yang pertama berguna, tetapi menunjukkan terlalu banyak output. Saya tidak tahu mengapa yang kedua tidak berhasil.

Martin Cleaver
sumber
Tail tidak memiliki "show all lines" maka 100000000 saya
Martin Cleaver
1
tail -n +1 -fke ekor dari awal.
Stéphane Chazelas
1
Yang kedua tidak bekerja karena yang paling kanan tailtidak bisa menghasilkan apa-apa sampai telah melihat baris terakhir dari inputnya (bagaimana ia tahu yang merupakan baris terakhir ke-10?) Yang tidak akan pernah terjadi karena tail -ftidak pernah berhenti.
Stéphane Chazelas
-1

Perintah cat -n [filename] | tailakan mendapatkan penghitungan cepat dan menampilkan catatan terbaru jika itu yang Anda cari.

The -fberalih membuatnya terus-menerus sampai melarikan diri - yang benar-benar tidak terdengar berlaku dalam skenario atau berlebihan.

wc -l [filename] akan mendapatkan hitungan garis di target

wc -l [filenameprefix]* akan menghitung semua baris di semua file yang cocok dengan pola dan bahkan melaporkan total ringkasan di akhir.

Detail yang lebih lengkap dapat menghasilkan respons yang lebih lengkap.

OtM
sumber
-1

Argumennya natau --lines(menggunakan cara yang sedikit berbeda, lihat di bawah):

$ tail -f -n 25 /path/to/file.txt

$ tail -f --lines=25 /path/to/file.txt

Lihat juga bantuannya:

$ tail --help
automatix
sumber
1
OP menginginkan nomor baris, bukan jumlah baris.
robbat2