Afficher le nom de fichier au début de chaque ligne lors de la personnalisation de plusieurs fichiers à la fois?


14

lors de la personnalisation de plusieurs fichiers à la fois comme indiqué ci-dessous, existe-t-il un moyen d'afficher le nom du fichier au début de chaque ligne?

tail -f one.log two.log

sortie courant

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

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

Vous cherchez quelque chose comme

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

Vous pouvez regarder l' -voption (verbeuse) pour la queue. Cela peut ne pas correspondre exactement à votre demande, mais c'est un début.
rahul

le multitail peut faire ça je pense
Gilles 'SO- arrête d'être mal'

Réponses:


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

\ merci {don_cristti}


@don_crissti, merci! (1) un fichier vs - plus de vin dans mon verre! (2) bonne idée. Je commence à faire quelque chose comme ça, mais je me suis dit lasily "personne ne fera de queue -f de fichiers avec des espaces" :) - J'utiliserai vos excellentes suggestions.
JJoao

pouvez-vous expliquer la longueur-8? pourquoi il est 8 ici, je ne connais que 8 œuvres.
Shicheng Guo

1
queue -n 1 * .txt | awk '/ ^ ==> / {a = substr ($ 0, 5, longueur-8); suivant} {imprimer un, $ 1} '| awk '$ 2> 0 {if ($ 2! ~ / chrY /) affiche $ 1}' | xargs -I {} qsub {}
Shicheng Guo

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

1
étonnamment / étonnamment votre awksolution magique joojoo fonctionne!
Trevor Boyd Smith

6

Réponse courte

GNU Parallel a un ensemble d'options intéressantes qui facilitent vraiment la réalisation de telles choses:

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

La sortie serait:

one.log: contenu de one.log ici ...
one.log: contenu de one.log ici ...
two.log: le contenu de two.log ici ...
two.log: le contenu de two.log ici ...

Plus d'explication

  • L'option --tagstring=strmarque chaque ligne de sortie avec la chaîne str . Depuis la parallel page de manuel :
--tagstring str
                Étiquetez les lignes avec une chaîne. Chaque ligne de sortie sera précédée de
                str et TAB (\ t). str peut contenir des chaînes de remplacement telles que {}.

                --tagstring est ignoré lors de l'utilisation de -u, --onall et --nonall.
  • Toutes les occurrences de {}seront remplacées par des arguments parallèles qui, dans ce cas, sont des noms de fichiers journaux; c'est-à one.log- dire et two.log(tous les arguments après :::).

  • L'option --line-bufferest requise car la sortie d'une commande (par exemple tail -f one.logou tail -f two.log) serait imprimée si cette commande est terminée. Depuis tail -fattendra la croissance du fichier, il est nécessaire d'imprimer la sortie en ligne qui le --line-bufferfait. Encore une fois à partir de la parallel page de manuel :

--line-buffer (test alpha)
                Sortie tampon en ligne. --group gardera la sortie
                ensemble pour tout un travail. --ungroup permet à la sortie de se mélanger avec
                une demi-ligne provenant d'un emploi et une demi-ligne provenant de
                un autre travail. --line-buffer s'adapte entre ces deux: GNU parallèle
                imprimera une ligne complète, mais permettra de mélanger des lignes de
                différents emplois.

2

Si tailn'est pas obligatoire, vous pouvez utiliser greppour y parvenir:

grep "" *.log

Cela affichera le nom de fichier comme préfixe de chaque ligne de sortie.

La sortie est interrompue si elle n'est *.logétendue qu'à un seul fichier. À cet égard:

grep '' /dev/null *.log

J'ai besoin d'afficher le nom du fichier en sortie de tail -fnon grep.
mtk

@serenesat cela imprimerait tout le contenu des fichiers n'est-ce pas? Le PO demandait que le nom du fichier soit imprimé lorsque la queue est spécifiée
rahul

vous pouvez également simplement faire --with-filenameou -Hforcer toujours le préfixe du nom de fichier.
Trevor Boyd Smith

j'aime vraiment cette réponse! fait exactement EXACTEMENT ce qui est nécessaire avec une solution de 13 caractères. par opposition à une awksolution délicate ou parallelqui n'est pas installée.
Trevor Boyd Smith

le seul problème est que si vos fichiers journaux contiennent 1 million de lignes. alors votre grep spammera 1 million de lignes vers la console (ou via ssh) ...
Trevor Boyd Smith

0

Mon idée serait de créer un seul fichier avec des journaux fusionnés à partir de plusieurs fichiers, comme quelqu'un l'a suggéré ici et de préfixer les noms de fichiers:

$ 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

Quelque chose avec xargset sedpourrait fonctionner:

$ xargs -I% -P0 sh -c "tail -f % | sed s/^/%:/g" <<EOT
one.log
two.log
EOT
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.