Mostra il nome del file all'inizio di ogni riga quando si esegue la coda di più file contemporaneamente?


14

quando si eseguono la coda di più file contemporaneamente come mostrato di seguito, esiste un modo per mostrare il nome del file all'inizio di ogni riga?

tail -f one.log two.log

uscita corrente

==> one.log <==
contents of one.log here...
contents of one.log here...

==> two.log <==
contents of one.log here...
contents of two.log here..

Alla ricerca di qualcosa di simile

one.log: contents of one.log here...
one.log: contents of one.log here...
two.log: contents of two.log here...
two.log: contents of two.log here...

Puoi vedere l' -vopzione (dettagliata) per la coda. Questo potrebbe non corrispondere esattamente alla tua richiesta, ma è un inizio.
rahul,

penso che il multitail possa farlo
Gilles 'SO- smetti di essere malvagio' il

Risposte:


7
tail  -f ...your-files | 
    awk '/^==> / {a=substr($0, 5, length-8); next}
                 {print a":"$0}'

\ {grazie don_cristti}


@don_crissti, grazie! (1) un file vs - niente più vino nel mio bicchiere! (2) buona idea. Comincio a fare una cosa del genere, ma ho detto a me stesso "nessuno farà la coda di file con spazi" :) - Userò i tuoi suggerimenti eccellenti.
JJoao,

puoi spiegare lunghezza 8? perché sono 8 qui, so solo 8 opere.
Shicheng Guo,

1
tail -n 1 * .txt | awk '/ ^ ==> / {a = substr ($ 0, 5, lunghezza-8); next} {stampa a, $ 1} '| awk '$ 2> 0 {if ($ 2! ~ / chrY /) stampa $ 1}' | xargs -I {} qsub {}
Shicheng Guo

@ShichengGuo, 8 = lunghezza ("==>") + lunghezza ("<==")
JJoao

1
sorprendentemente / sorprendentemente la tua awksoluzione magica joojoo funziona!
Trevor Boyd Smith,

6

Risposta breve

GNU Parallel ha una serie di belle opzioni che rendono davvero facile fare queste cose:

parallel --tagstring "{}:" --line-buffer tail -f {} ::: one.log two.log

L'output sarebbe:

one.log: contenuto di one.log qui ...
one.log: contenuto di one.log qui ...
two.log: contenuto di two.log qui ...
two.log: contenuto di two.log qui ...

Più spiegazione

  • L'opzione --tagstring=strcontrassegna ciascuna riga di output con stringa str . Dalla parallel pagina man :
--tagstring str
                Contrassegnare le linee con una stringa. Ogni linea di uscita verrà preceduta da
                str e TAB (\ t). str può contenere stringhe di sostituzione come {}.

                --tagstring viene ignorato quando si utilizza -u, --onall e --nonall.
  • Tutte le occorrenze di {}saranno sostituite da argomenti paralleli che, in questo caso, sono nomi di file di registro; ie one.loge two.log(tutti gli argomenti dopo :::).

  • L'opzione --line-bufferè obbligatoria perché l'output di un comando (ad es. tail -f one.logO tail -f two.log) verrebbe stampato al termine del comando. Dal momento tail -fche attenderà la crescita dei file, è necessario stampare l'output sulla base della linea che lo --line-bufferfa. Sempre dalla parallel pagina man :

--line-buffer (test alfa)
                Uscita buffer su linea. --group manterrà l'output
                insieme per un intero lavoro. --ungroup consente all'output di confondersi
                mezza linea proveniente da un lavoro e mezza linea proveniente da
                un altro lavoro. --line-buffer si inserisce tra questi due: GNU parallelo
                stamperà una linea intera, ma consentirà di mescolare le linee di
                lavori diversi.

2

Se tailnon è obbligatorio, è possibile utilizzare grepper raggiungere questo obiettivo:

grep "" *.log

Questo stamperà il nome del file come prefisso di ogni riga di output.

L'output si interrompe se si *.logespande in un solo file. A questo proposito:

grep '' /dev/null *.log

Devo mostrare il nome del file in output di tail -fno grep.
mtk,

@serenesat questo stamperebbe semplicemente l'intero contenuto dei file, no? L'OP chiedeva di stampare il nome del file quando si specifica tail
rahul

puoi anche semplicemente fare --with-filenameo -Hforzare sempre anteporre il nome file.
Trevor Boyd Smith,

amo davvero questa risposta! fa esattamente ESATTAMENTE ciò che è necessario con una soluzione lunga 13 caratteri. al contrario di una awksoluzione difficile o parallelche non è installata.
Trevor Boyd Smith,

l'unico problema è che se i file di log sono lunghi 1 milione di righe. quindi il tuo grep invierà spam a 1 milione di righe su console (o su ssh) ...
Trevor Boyd Smith,

0

La mia idea sarebbe quella di creare un singolo file con registri uniti da diversi file, come qualcuno ha suggerito qui e anteporre nomi di file:

$ tail -f /var/log/syslog | sed -u -E 's,(^.+$),/var/log/syslog: \1,g' >> /tmp/LOG &&
$ tail -f /var/log/Xorg.0.log | sed -u -E 's,(^.+$),/var/log/Xorg.0.log: \1,g' >> /tmp/LOG &&
$ tail -f /tmp/LOG

0

Qualcosa con xargse sedpotrebbe funzionare:

$ xargs -I% -P0 sh -c "tail -f % | sed s/^/%:/g" <<EOT
one.log
two.log
EOT
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.