Frage

Am Ende habe ich ein kurzes kleines Skript dafür in Python geschrieben, aber ich habe mich gefragt, ob es ein Dienstprogramm gibt, in das man Text eingeben kann, das jeder Zeile etwas Text voranstellt – in meinem speziellen Fall einen Zeitstempel.Idealerweise wäre die Verwendung etwa so:

cat somefile.txt | prepend-timestamp

(Bevor Sie sed antworten, habe ich Folgendes versucht:

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

Dadurch wird der Datumsbefehl jedoch nur einmal ausgewertet, wenn sed ausgeführt wird, sodass jeder Zeile fälschlicherweise derselbe Zeitstempel vorangestellt wird.)

War es hilfreich?

Lösung

Könnte es versuchen awk:

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

Möglicherweise müssen Sie dies sicherstellen <command> erzeugt eine zeilengepufferte Ausgabe, d. h.es leert seinen Ausgabestrom nach jeder Zeile;der Zeitstempel awk adds ist die Zeit, zu der das Ende der Zeile in der Eingabepipe angezeigt wurde.

Wenn awk Fehler anzeigt, versuchen Sie es gawk stattdessen.

Andere Tipps

ts aus moreutils wird jeder Eingabezeile, die Sie ihm geben, einen Zeitstempel voranstellen.Sie können es auch mit strftime formatieren.

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

Um es zu installieren:

sudo apt-get install moreutils

kommentieren, verfügbar über diesen Link oder als annotate-output im Debian devscripts Paket.

$ 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

Destillieren Sie die gegebenen Antworten auf die einfachste mögliche:

unbuffer $COMMAND | ts

Unter Ubuntu stammen sie aus den Paketen „expect-dev“ und „moreutils“.

sudo apt-get install expect-dev moreutils

Wie wäre es damit?

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

Gemessen an Ihrem Wunsch, Live-Zeitstempel zu erhalten, möchten Sie vielleicht eine Live-Aktualisierung einer Protokolldatei oder ähnliches durchführen?Vielleicht

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

Ich werde das einfach da rauswerfen:Es gibt ein paar Dienstprogramme daemontools angerufen tai64n Und tai64nlocal die dafür gedacht sind, den Protokollnachrichten Zeitstempel voranzustellen.

Beispiel:

cat file | tai64n | tai64nlocal

Kierons Antwort ist bisher die beste.Wenn Sie Probleme haben, weil das erste Programm seine Daten puffert, können Sie das Programm „unbuffer“ verwenden:

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

Es ist auf den meisten Linux-Systemen standardmäßig installiert.Wenn Sie es selbst erstellen müssen, ist es Teil des Expect-Pakets

http://expect.nist.gov

Verwenden Sie den Befehl read(1), um jeweils eine Zeile aus der Standardeingabe zu lesen, und geben Sie dann die Zeile mit vorangestelltem Datum im Format Ihrer Wahl mit date(1) aus.

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

Ich bin kein Unix-Typ, aber ich denke, Sie können es verwenden

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 . " " . $_;
}'

Hier ist meine awk-Lösung (von einem Windows/XP-System mit installierten MKS Tools im Verzeichnis C:\bin).Es wurde entwickelt, um das aktuelle Datum und die aktuelle Uhrzeit in der Form mm/dd hh:mm am Anfang jeder Zeile hinzuzufügen, nachdem dieser Zeitstempel beim Lesen jeder Zeile vom System abgerufen wurde.Sie könnten natürlich das BEGIN-Muster verwenden, um den Zeitstempel einmal abzurufen und diesen Zeitstempel jedem Datensatz hinzuzufügen (alles gleich).Ich habe dies getan, um eine Protokolldatei, die gerade generiert wurde, mit dem Zeitstempel zum Zeitpunkt der Generierung der Protokollnachricht auf stdout zu markieren.

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

Dabei ist „Muster“ eine Zeichenfolge oder ein regulärer Ausdruck (ohne Anführungszeichen), der in der Eingabezeile abgeglichen werden soll, und ist optional, wenn Sie alle Eingabezeilen abgleichen möchten.

Dies sollte auch auf Linux/UNIX-Systemen funktionieren. Entfernen Sie einfach das C\:\\bin\\ aus der Zeile

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

Dies setzt natürlich voraus, dass Sie mit dem Befehl „date“ zum standardmäßigen Linux/UNIX-Befehl zum Anzeigen/Festlegen des Datums ohne spezifische Pfadinformationen gelangen (d. h. Ihre Umgebungsvariable PATH ist korrekt konfiguriert).

Mischen Sie einige Antworten oben von natevw und Frank Ch.Eigler.

Es hat Millisekunden und ist leistungsfähiger als ein externer Aufruf date Befehl jedes Mal und Perl ist auf den meisten Servern zu finden.

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);
  '

Alternative Version mit Flush und Read in einer Schleife:

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`/"

Sie können dies tun (mit gnu/sed):

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

Beispiel:

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

Natürlich können Sie auch andere Optionen des Programms nutzen Datum.einfach ersetzen date +%T mit dem, was Sie brauchen.

Die Antwort von caerwyn kann als Unterroutine ausgeführt werden, was die neuen Prozesse pro Zeile verhindern würde:

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

echo testing 123 |timestamp

Haftungsausschluss:Die von mir vorgeschlagene Lösung ist kein in Unix integriertes Dienstprogramm.

Ich hatte vor ein paar Tagen ein ähnliches Problem.Mir gefielen die Syntax und die Einschränkungen der oben genannten Lösungen nicht, also habe ich schnell ein Programm in Go zusammengestellt, das die Arbeit für mich erledigte.

Sie können das Tool hier überprüfen: Vorzeit

Es gibt vorgefertigte ausführbare Dateien für Linux, MacOS und Windows im Veröffentlichungen Abschnitt des GitHub-Projekts.

Das Tool verarbeitet unvollständige Ausgabezeilen und hat (aus meiner Sicht) eine kompaktere Syntax.

<command> | preftime

Es ist nicht ideal, aber ich würde es gerne teilen, falls es jemandem hilft.

mach es mit date Und tr Und xargs unter OSX:

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

Wenn Sie Millisekunden möchten:

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

Beachten Sie jedoch, dass date Ihnen unter OSX nicht die Option %N bietet, sodass Sie gdate installieren müssen (brew install coreutils) und komme so schließlich zu folgendem Ergebnis:

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

Wenn der Wert, den Sie voranstellen, in jeder Zeile derselbe ist, starten Sie Emacs mit der Datei, dann:

Strg + <Leerzeichen>

am Anfang der Datei (um diese Stelle zu markieren) und scrollen Sie dann nach unten zum Anfang der letzten Zeile (Alt + > geht zum Ende der Datei ...was wahrscheinlich auch die Umschalttaste erfordert, dann Strg + a, um zum Anfang dieser Zeile zu gelangen) und:

Strg + X R T

Dies ist der Befehl zum Einfügen in das gerade angegebene Rechteck (ein Rechteck mit der Breite 0).

21.08.2008 18:45 Uhr <Eingabe>

Oder was auch immer Sie voranstellen möchten ...Dann sehen Sie, dass dieser Text jeder Zeile innerhalb des Rechtecks ​​mit der Breite 0 vorangestellt wird.

AKTUALISIEREN:Mir ist gerade aufgefallen, dass Sie nicht das GLEICHE Datum haben möchten, also wird das nicht funktionieren ...Obwohl Sie dies in Emacs möglicherweise mit einem etwas komplizierteren benutzerdefinierten Makro tun können, ist diese Art der Rechteckbearbeitung dennoch ziemlich gut zu wissen ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top