Question

J'ai fini par écrire un petit script rapide pour cela en Python, mais je me demandais s'il existait un utilitaire dans lequel vous pourriez insérer du texte et qui ajouterait du texte à chaque ligne - dans mon cas spécifique, un horodatage.Idéalement, l'utilisation serait quelque chose comme :

cat somefile.txt | prepend-timestamp

(Avant de répondre à sed, j'ai essayé ceci :

cat somefile.txt | sed "s/^/`date`/"

Mais cela n'évalue la commande date qu'une seule fois lorsque sed est exécuté, donc le même horodatage est ajouté de manière incorrecte à chaque ligne.)

Était-ce utile?

La solution

Pourrait essayer d'utiliser awk:

<command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; fflush(); }'

Vous devrez peut-être vous assurer que <command> produit une sortie en mémoire tampon de ligne, c'est-à-direil vide son flux de sortie après chaque ligne ;l'horodatage awk ajoute sera l'heure à laquelle la fin de la ligne est apparue sur son tube d'entrée.

Si awk affiche des erreurs, essayez gawk plutôt.

Autres conseils

ts depuis plusutils ajoutera un horodatage à chaque ligne d'entrée que vous lui donnez.Vous pouvez également le formater en utilisant strftime.

$ echo 'foo bar baz' | ts
Mar 21 18:07:28 foo bar baz
$ echo 'blah blah blah' | ts '%F %T'
2012-03-21 18:07:30 blah blah blah
$ 

Pour l'installer :

sudo apt-get install moreutils

annoter, disponible via ce lien ou sous forme annotate-output dans Debian devscripts emballer.

$ echo -e "a\nb\nc" > lines
$ annotate-output cat lines
17:00:47 I: Started cat lines
17:00:47 O: a
17:00:47 O: b
17:00:47 O: c
17:00:47 I: Finished with exitcode 0

Distiller les réponses données à la plus simple possible :

unbuffer $COMMAND | ts

Sur Ubuntu, ils proviennent des packages expect-dev et moreutils.

sudo apt-get install expect-dev moreutils

Que dis-tu de ça?

cat somefile.txt | perl -pne 'print scalar(localtime()), " ";'

À en juger par votre désir d'obtenir des horodatages en direct, vous souhaitez peut-être effectuer une mise à jour en direct d'un fichier journal ou quelque chose du genre ?Peut être

tail -f /path/to/log | perl -pne 'print scalar(localtime()), " ";' > /path/to/log-with-timestamps

Je vais juste jeter ça là-bas :il y a une paire d'utilitaires dans Daemon Tools appelé tai64n et tai64nlocal qui sont conçus pour ajouter des horodatages pour enregistrer les messages.

Exemple:

cat file | tai64n | tai64nlocal

La réponse de Kieron est la meilleure jusqu'à présent.Si vous rencontrez des problèmes parce que le premier programme met sa sortie en mémoire tampon, vous pouvez utiliser le programme unbuffer :

unbuffer <command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; }'

Il est installé par défaut sur la plupart des systèmes Linux.Si vous devez le construire vous-même, cela fait partie du package attendu

http://expect.nist.gov

Utilisez la commande read(1) pour lire une ligne à la fois à partir de l'entrée standard, puis affichez la ligne précédée de la date dans le format de votre choix en utilisant date(1).

$ cat timestamp
#!/bin/sh
while read line
do
  echo `date` $line
done
$ cat somefile.txt | ./timestamp

Je ne suis pas un gars Unix, mais je pense que vous pouvez utiliser

gawk '{print strftime("%d/%m/%y",systime()) $0 }' < somefile.txt
#! /bin/sh
unbuffer "$@" | perl -e '
use Time::HiRes (gettimeofday);
while(<>) {
        ($s,$ms) = gettimeofday();
        print $s . "." . $ms . " " . $_;
}'

Voici ma solution awk (à partir d'un système Windows/XP avec MKS Tools installé dans le répertoire C:\bin).Il est conçu pour ajouter la date et l'heure actuelles sous la forme mm/jj hh:mm au début de chaque ligne après avoir récupéré cet horodatage du système lors de la lecture de chaque ligne.Vous pouvez, bien sûr, utiliser le modèle BEGIN pour récupérer l'horodatage une fois et l'ajouter à chaque enregistrement (tout de même).J'ai fait cela pour marquer un fichier journal généré sur la sortie standard avec l'horodatage au moment où le message de journal a été généré.

/"pattern"/ "C\:\\\\bin\\\\date '+%m/%d %R'" | getline timestamp;
print timestamp, $0;

où "motif" est une chaîne ou une expression régulière (sans les guillemets) à faire correspondre dans la ligne d'entrée, et est facultatif si vous souhaitez faire correspondre toutes les lignes d'entrée.

Cela devrait également fonctionner sur les systèmes Linux/UNIX, supprimez simplement le C\:\\bin\\ en quittant la ligne

             "date '+%m/%d %R'" | getline timestamp;

Ceci, bien sûr, suppose que la commande "date" vous amène à la commande standard Linux/UNIX date display/set sans informations de chemin spécifiques (c'est-à-dire que votre variable PATH d'environnement est correctement configurée).

Mélanger quelques réponses ci-dessus de natevw et Frank Ch.Eigler.

Il a des millisecondes, fonctionne mieux que d'appeler un externe date commande à chaque fois et Perl peut être trouvé sur la plupart des serveurs.

tail -f log | perl -pne '
  use Time::HiRes (gettimeofday);
  use POSIX qw(strftime);
  ($s,$ms) = gettimeofday();
  print strftime "%Y-%m-%dT%H:%M:%S+$ms ", gmtime($s);
  '

Version alternative avec flush et lecture en boucle :

tail -f log | perl -pne '
  use Time::HiRes (gettimeofday); use POSIX qw(strftime);
  $|=1;
  while(<>) {
    ($s,$ms) = gettimeofday();
    print strftime "%Y-%m-%dT%H:%M:%S+$ms $_", gmtime($s);
  }'
$ cat somefile.txt | sed "s/^/`date`/"

vous pouvez le faire (avec gnu/sed):

$ some-command | sed "x;s/.*/date +%T/e;G;s/\n/ /g"

exemple:

$ { echo 'line1'; sleep 2; echo 'line2'; } | sed "x;s/.*/date +%T/e;G;s/\n/ /g"
20:24:22 line1
20:24:24 line2

bien sûr, vous pouvez utiliser d'autres options du programme date.il suffit de remplacer date +%T avec ce dont vous avez besoin.

La réponse de Caerwyn peut être exécutée comme un sous-programme, ce qui empêcherait les nouveaux processus par ligne :

timestamp(){
   while read line
      do
         echo `date` $line
      done
}

echo testing 123 |timestamp

Clause de non-responsabilité:la solution que je propose n'est pas un utilitaire intégré à Unix.

J'ai été confronté à un problème similaire il y a quelques jours.Je n'ai pas aimé la syntaxe et les limites des solutions ci-dessus, j'ai donc rapidement mis en place un programme dans Go pour faire le travail à ma place.

Vous pouvez consulter l'outil ici : avant-première

Il existe des exécutables prédéfinis pour Linux, MacOS et Windows dans le Sorties du projet GitHub.

L'outil gère les lignes de sortie incomplètes et a (de mon point de vue) une syntaxe plus compacte.

<command> | preftime

Ce n'est pas idéal, mais je pensais le partager au cas où cela aiderait quelqu'un.

le faire avec date et tr et xargs sous OSX :

alias predate="xargs -I{} sh -c 'date +\"%Y-%m-%d %H:%M:%S\" | tr \"\n\" \" \"; echo \"{}\"'"
<command> | predate

si vous voulez des millisecondes :

alias predate="xargs -I{} sh -c 'date +\"%Y-%m-%d %H:%M:%S.%3N\" | tr \"\n\" \" \"; echo \"{}\"'"

mais notez que sous OSX, date ne vous donne pas l'option %N, vous devrez donc installer gdate (brew install coreutils) et on arrive finalement à ceci :

alias predate="xargs -I{} sh -c 'gdate +\"%Y-%m-%d %H:%M:%S.%3N\" | tr \"\n\" \" \"; echo \"{}\"'"

Si la valeur que vous ajoutez est la même sur chaque ligne, lancez Emacs avec le fichier, puis :

Ctrl + <espace>

au début du fichier (pour marquer cet endroit), puis faites défiler jusqu'au début de la dernière ligne (Alt + > ira à la fin du fichier...ce qui impliquera probablement aussi la touche Shift, puis Ctrl + a pour aller au début de cette ligne) et :

Ctrl + X r t

Quelle est la commande à insérer au niveau du rectangle que vous venez de spécifier (un rectangle de largeur 0).

2008-8-21 18h45 <entrer>

Ou tout ce que vous voulez ajouter au début...alors vous verrez ce texte ajouté à chaque ligne dans le rectangle de largeur 0.

MISE À JOUR:Je viens de réaliser que tu ne veux pas la MÊME date, donc ça ne marchera pas...bien que vous puissiez peut-être le faire dans emacs avec une macro personnalisée légèrement plus compliquée, mais quand même, ce type d'édition de rectangle est plutôt agréable à connaître...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top