tail -f, ma con numeri di riga


21

Sto cercando di vedere quante volte foo barappare /var/log/foo.logentro un tempo arbitrario su un server remoto, ma nulla di ciò che ho provato finora ha funzionato.

Ho già uno script timer che uso per tenere traccia di quanto tempo è passato da quando ho iniziato a fare la coda /var/log/foo.log, e ora vorrei solo un modo per dire quante volte foo barè apparso nell'output della coda.

Ho cercato su Google, ma non ho trovato nulla di pertinente nelle prime 10 pagine di risultati.

Ecco cosa ho provato con risultati frustranti:

## 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}'

Ho anche provato a scrivere una sceneggiatura di sed che avrebbe funzionato in questo modo tail -f, ma ho fatto progressi limitati a niente.

NOTA

il server remoto esegue una versione precedente di coreutils e l'aggiornamento è un'opzione, ma NON è in alcun modo la soluzione desiderata.


2
In che modo non funziona? Prova l' --line-bufferedopzione a grep. Oppuretail -f ... | awk '/foo bar/{print ++n, $0}'
Stéphane Chazelas,

Perché non funziona sul telecomando? Esempio:tail -f /var/log/log.log | awk '{ printf "[%d]> %s\n", NR+1 ,$0; fflush(stdout); }'

Risposte:


29
tail -f | nl

funziona per me ed è il primo a cui ho pensato: se vuoi davvero che le righe siano numerate da 1 e non con il numero di riga reale del file guardato. Se lo si desidera, aggiungere grepeventualmente al posto appropriato (prima o dopo nl). Tuttavia, ricorda che può verificarsi il buffering. Nel mio caso particolare, grepha l' --line-bufferedopzione, ma nlbuffer è l'output e non ha un'opzione per spegnerlo. Quindi la tail | nl | grepcombo non scorre davvero bene.

Detto ciò,

tail -f | grep -n pattern

funziona anche per me. La numerazione ricomincia dall'inizio del "tailing" anziché dall'inizio dell'intero file di registro.


la versione di grep in esecuzione sul server non ha -nun'opzione.
Alexej Magura,

ha, tuttavia, la lunga opzione --line-number: tail -f /var/log/foo.log | grep foo\ bar --line-numberfunziona!
Alexej Magura,

1
È interessante - non ho verificato POSIX in quanto tale, ma la manpage GNU grep dice: -n è specificato da POSIX .
peterph

16

Penso che sia meglio ..

less -N +F <filepath>

2
Potresti spiegare perché pensi che sia meglio?
Navigatron,

Questa è una modifica di grandi dimensioni, sto ripristinando.
Adam Eberlin,

3
Mostra il numero di riga prendendo come riferimento l'intero file. coda -f | nl mostra il numero di riga prendendo come riferimento il primo output di coda.
Rafaelvalle,

Questo è molto utile e affronta il titolo del PO, ma non la loro domanda . Volevano sapere quante volte X appare in un file: P
Timmah, il

6

Puoi anche reindirizzare l'output less, ha una funzione di numero di riga, -Nche ti permetterebbe di scorrere avanti e indietro nel registro.

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

Esempio

  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://sam@sparkleshare.jake      
  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/

NOTA: prendere nota dell'output. Potrebbe piacerti o meno questa funzione, ma ci vorranno linee lunghe e le taglierai in modo che continuino sulla riga successiva, mantenendo comunque lo stesso numero di riga corrispondente. Trovo questa funzione inestimabile quando analizzo i file di registro che sono larghi! Puoi vedere l'effetto di questa funzione sulle linee 6 e 8 .


Questo non è chiaro. Dove viene specificato il nome file? Dovrebbe essere chiarito, osservando che l'output è numerato da 1 a partire dalle ultime 10 righe del nome file, poiché questo è il comportamento predefinito di tail. Per quanto riguarda le linee lunghe, tale comportamento è attivato / disattivato durante l' lessutilizzo -S.
ILMostro_7,

2

Per eseguire il grep delle nuove righe solo nel file di registro man mano che arrivano con il loro numero di riga, è possibile:

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

(con mawk, ti consigliamo di aggiungere l' -Winteractiveopzione per impedire il suo buffering di input (!)).

wc -llegge le righe che erano già lì e le conta (i caratteri di nuova riga che significa che funziona ancora anche se l'ultima riga non è ancora piena), e poi noi tail -fgli altri (a partire da dove ha wcsmesso di leggere) e diciamo awkqual è il numero di riga di il primo che vede.


scegliendo lcome nome della variabile mi ha fatto socchiudere gli occhi su $ l, pensando che fosse $1^^ (ma come so (e 100% fiducia) tu, ho riletto e ho visto la verità). Solo per curiosità: per evitare qualche "condizione di competizione" tra il wc -le il tail -f(se il file cresce velocemente, si possono scartare alcune righe e quindi il NR parte dal numero sbagliato), è possibile $linvece saltare le righe? (e quale limite c'è per la coda -nin posix e in gnu?). Forse con un file intermedio temporaneo?
Olivier Dulac,

@OlivierDulac, tail -n +1(leggi qualsiasi cosa dalla posizione di partenza) risolve i problemi relativi alle condizioni di gara. Leggerà le righe che non erano nel file al momento wc -lterminato, dalla posizione esatta wclasciato. Quindi NR avrà la posizione giusta indipendentemente da quante righe sono state scritte tra la wcfine e l' tailinizio. È se ti dicessi taildi iniziare da qualche posizione rispetto alla fine del file che avresti problemi.
Stéphane Chazelas,

oh, interessante: in effetti, i dati si accumulano in stdin mentre nulla lo legge (tra la fine del wc fino all'inizio della testa) ... Avrei dovuto rendermene conto. Grazie. Ora vedo perché tu "<file". intelligente, come al solito :)
Olivier Dulac il

1
@OlivierDulac, sulle limitazioni (che non si applicano tail -n +1qui), per i file regolari, la maggior parte delle implementazioni non ne ha una in quanto possono iniziare dalla fine e seekviceversa fino a quando non trovano l'ennesima riga senza dover memorizzare più di un valore di dati in memoria. Per input non ricercabili, è qui che puoi imbatterti in limiti. POSIX richiede che le implementazioni siano in grado di memorizzare almeno 10 x LINE_MAX byte (LINE_MAX pari almeno a 2048). La coda GNU non ha limiti oltre alla memoria AFAIK
Stéphane Chazelas il

0

Se vuoi numerare dall'inizio avresti bisogno di grep -n da applicare a tutte le linee.

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

Se poi avessi voluto solo mostrare gli ultimi 10, avrei pensato di poter ricodificare il file:

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

Il primo è utile, ma mostra un output eccessivo. Non so perché il secondo non funzioni.


Tail non ha un "show all lines" quindi il mio 100000000
Martin Cleaver,

1
tail -n +1 -fa coda dall'inizio.
Stéphane Chazelas,

1
Il secondo non funziona perché l'estrema destra tailnon può emettere nulla fino a quando non vede l'ultima riga del suo input (come fa a sapere qual è la decima riga?) Che non accadrà tail -fmai perché non si ferma mai.
Stéphane Chazelas,

-1

Il comando cat -n [filename] | tailotterrà un conteggio rapido e visualizzerà i record più recenti se è quello che stai cercando.

L' -finterruttore lo rende persistente fino alla fuga, il che in realtà non sembra applicabile nel tuo scenario o è ridondante.

wc -l [filename] otterrà un conteggio delle linee nel bersaglio

wc -l [filenameprefix]* conterà tutte le righe in tutti i file corrispondenti allo schema e alla fine segnalerà anche un totale di riepilogo.

Dettagli più completi possono fornire risposte più complete.


-1

È l'argomento no --lines(usato modi leggermente diversi, vedi sotto):

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

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

Vedi anche l'aiuto:

$ tail --help

1
L'OP vuole numeri di riga, non un numero di righe.
robbat2,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.