¿Mostrar el nombre del archivo al comienzo de cada línea al seguir múltiples archivos a la vez?

14

al seguir múltiples archivos a la vez como se muestra a continuación, ¿hay alguna forma de mostrar el nombre del archivo al comienzo de cada línea?

tail -f one.log two.log

salida de corriente

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

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

Buscando algo como

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...
mtk
fuente
Puede mirar la -vopción (detallada) para la cola. Es posible que esto no coincida exactamente con su solicitud, pero es un comienzo.
rahul
multitail puede hacer esto, creo
Gilles 'SO- deja de ser malvado'

Respuestas:

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

\ gracias {don_cristti}

JJoao
fuente
@don_crissti, gracias! (1) un archivo vs - ¡no más vino a mi copa! (2) buena idea. Empiezo a hacer algo como esto, pero me dije a mí mismo "nadie hará cola de archivos con espacios" :) - Usaré sus excelentes sugerencias.
JJoao
¿Puedes explicar longitud-8? por qué son 8 aquí, sé que solo 8 funcionan.
Shicheng Guo
1
cola -n 1 * .txt | awk '/ ^ ==> / {a = substr ($ 0, 5, longitud-8); siguiente} {print a, $ 1} '| awk '$ 2> 0 {if ($ 2! ~ / chrY /) print $ 1}' | xargs -I {} qsub {}
Shicheng Guo
@ShichengGuo, 8 = longitud ("==>") + longitud ("<==")
JJoao
1
¡Sorprendentemente / asombrosamente su awksolución mágica joojoo funciona!
Trevor Boyd Smith
6

Respuesta corta

GNU Parallel tiene un conjunto de buenas opciones que hacen que sea realmente fácil hacer tales cosas:

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

El resultado sería:

one.log: contenido de one.log aquí ...
one.log: contenido de one.log aquí ...
two.log: contenido de two.log aquí ...
two.log: contenido de two.log aquí ...

Más explicaciones

  • La opción --tagstring=stretiqueta cada línea de salida con string str . Desde la parallel página del manual :
--tagstring str
                Etiquetar líneas con una cadena. Cada línea de salida se antepondrá con
                str y TAB (\ t). str puede contener cadenas de reemplazo como {}.

                --tagstring se ignora cuando se usa -u, --onall y --nonall.
  • Todas las apariciones de {}serán reemplazadas por argumentos paralelos que, en este caso, son nombres de archivos de registro; es decir one.logy two.log(todos los argumentos posteriores :::).

  • La opción --line-bufferes necesaria porque la salida de un comando (p. Ej. tail -f one.logO tail -f two.log) se imprimirá si ese comando finaliza. Dado tail -fque esperará el crecimiento del archivo, es necesario imprimir la salida en línea, lo --line-bufferque lo hace. De nuevo desde la parallel página del manual :

--line-buffer (prueba alfa)
                Salida de buffer en línea. --group mantendrá la salida
                juntos por todo un trabajo. --ungroup permite que la salida se mezcle con
                media línea de un trabajo y media línea de
                otro trabajo. --line-buffer se ajusta entre estos dos: GNU paralelo
                imprimirá una línea completa, pero permitirá mezclar líneas de
                trabajos diferentes.
dibujante
fuente
2

Si tailno es obligatorio, puede utilizar greppara lograr esto:

grep "" *.log

Esto imprimirá el nombre del archivo como el prefijo de cada línea de salida.

La salida se rompe si se *.logexpande a un solo archivo. A este respecto:

grep '' /dev/null *.log
serenesat
fuente
Necesito mostrar el nombre del archivo en la salida de tail -fnot grep.
mtk
@serenesat esto solo imprimiría todo el contenido de los archivos, ¿no? El OP pedía que se imprimiera el nombre del archivo cuando se especifica la cola
rahul
también puede simplemente hacer --with-filenameo -Hforzar siempre el antecedente de nombre de archivo.
Trevor Boyd Smith el
Realmente me encanta esta respuesta! hace exactamente lo que se necesita con una solución que tiene 13 caracteres de longitud. a diferencia de la awksolución difícil o parallelque no está instalada.
Trevor Boyd Smith
El único problema es que si sus archivos de registro tienen 1 millón de líneas de largo. entonces su grep enviará 1 millón de líneas a la consola (o sobre ssh) ...
Trevor Boyd Smith
0

Mi idea sería crear un solo archivo con registros combinados de varios archivos, como alguien sugirió aquí y anteponer nombres de archivo:

$ 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
Arkadiusz Drabczyk
fuente
0

Algo con xargsy sedpodría funcionar:

$ xargs -I% -P0 sh -c "tail -f % | sed s/^/%:/g" <<EOT
one.log
two.log
EOT
Flo Mismo
fuente