¿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...

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}


@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.

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

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

0

Algo con xargsy sedpodría funcionar:

$ xargs -I% -P0 sh -c "tail -f % | sed s/^/%:/g" <<EOT
one.log
two.log
EOT
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.