Am Ende habe ich in Python ein kurzes kleines Skript dafür geschrieben, aber ich habe mich gefragt, ob es ein Dienstprogramm gibt, in das Sie Text einfügen können, das jeder Zeile einen Text voranstellt - in meinem speziellen Fall einen Zeitstempel. Im Idealfall wäre die Verwendung so etwas wie:
cat somefile.txt | prepend-timestamp
(Bevor Sie sed antworten, habe ich Folgendes versucht:
cat somefile.txt | sed "s/^/`date`/"
Der Datumsbefehl wird jedoch nur einmal ausgewertet, wenn sed ausgeführt wird, sodass jeder Zeile derselbe Zeitstempel falsch vorangestellt wird.)
cat somefile.txt
ein bisschen "irreführend"? Ich würde erwarten, dass es "sofort" passiert und einen einzigen Zeitstempel hat. Wäre das nicht ein besseres Testprogramm(echo a; sleep 1; echo b; sleep 3; echo c; sleep 2)
?Antworten:
Könnte versuchen mit
awk
:Möglicherweise müssen Sie sicherstellen, dass
<command>
eine zeilengepufferte Ausgabe erzeugt wird, dh der Ausgabestream wird nach jeder Zeile geleert. Der hinzugefügte Zeitstempelawk
ist die Zeit, zu der das Zeilenende auf der Eingangsleitung angezeigt wurde.Wenn awk Fehler anzeigt, versuchen Sie es
gawk
stattdessen.quelle
gawk
stattdessen installieren und verwendenawk
. Wenn Sie MacPorts haben:sudo port install gawk
awk
'sstrftime()
keine Millisekundengenauigkeit. Sie können jedoch dendate
Befehl verwenden. Grundsätzlich schneiden Sie Nanosekunden nur auf drei Zeichen. Es wird so aussehen :COMMAND | while read -r line; do echo "$(date '+%Y-%m-%d %T.%3N') $line"; done
. Beachten Sie, dass Sie% H:% M:% S mit% T abkürzen können. Wenn Sieawk
aus irgendeinem Grund immer noch verwenden möchten , können Sie Folgendes tun:COMMAND | awk '{ "date +%Y-%m-%d\\ %T.%3N" | getline timestamp; print timestamp, $0; fflush(); }'
ts
from moreutils stellt jeder Eingabezeile, die Sie eingeben , einen Zeitstempel voran . Sie können es auch mit strftime formatieren.So installieren Sie es:
quelle
bad command 2>&1 | ts
ergibtJan 29 19:58:31 -bash: bad: command not found
2014 Mar 21 18:07:28
. Wie bekomme ich es?strftime
als Argument an:[.. command ..] | ts '%Y %b %d %T'
zum Beispiel.brew install moreutils
. Um UTC auszugeben, können Sie TZ lokal einstellen, zBls -l |TZ=UTC ts '%Y-%m-%dT%H:%M:%SZ'
ruby -e "puts 1; STDOUT.flush; sleep 1; puts 2; STDOUT.flush; sleep 2; puts 3" | ts '%F %T'
kommentieren , verfügbar über diesen Link oder wie
annotate-output
im Debian-devscripts
Paket.quelle
Destillieren Sie die gegebenen Antworten auf die einfachste mögliche:
Unter Ubuntu stammen sie aus den Paketen Expect-Dev und Moreutils.
quelle
expect
nicht soexpect-dev
, aber das letztere zieht das erstere an, damit dies funktioniert. (Ubuntu 14.10, ich frage mich, ob die Binärdatei irgendwann in ein anderes Paket verschoben wurde.)expect-dev
unbuffer $COMMAND | ts -s %.s
(-s
wenn für die verstrichene Zeit und%.s
für die Zeit in Sekunden mit Bruchteil)Wie wäre es damit?
Nach Ihrem Wunsch nach Live-Zeitstempeln zu urteilen, möchten Sie vielleicht eine Protokolldatei oder etwas anderes live aktualisieren? Vielleicht
quelle
tail -f /path/to/log | perl -pne 'use POSIX qw(strftime); print strftime "%Y-%m-%dT%H:%M:%SZ ", gmtime();'
ein Datum im ISO8601 / RFC3339-Stil anstelle des verrückten Datums erhalten, das die einfachere Version liefert.BEGIN { $|++; }
vor der Druckanweisung hinzuzufügen , damit Perl die Ausgabe mit jeder Zeile leert.ls | perl -pne 'print localtime." "'
. Die skalare Konvertierung erfolgt aufgrund der Verkettung von Zeichenfolgen.-p
und-n
Optionen? Es scheint-n
redundant zu sein, wenn Sie angegeben haben-p
.Ich werde das hier rauswerfen : In daemontools gibt es zwei Dienstprogramme namens tai64n und tai64nlocal , mit denen Zeitstempel vorangestellt werden, um Nachrichten zu protokollieren.
Beispiel:
quelle
Kierons Antwort ist die bisher beste. Wenn Sie Probleme haben, weil das erste Programm seinen Ausgang puffert, können Sie das Entpufferungsprogramm verwenden:
Es ist standardmäßig auf den meisten Linux-Systemen installiert. Wenn Sie es selbst erstellen müssen, ist es Teil des Expect-Pakets
http://expect.nist.gov
quelle
Verwenden Sie den Befehl read (1), um jeweils eine Zeile aus der Standardeingabe zu lesen, und geben Sie dann die Zeile mit dem vorangestellten Datum in dem Format Ihrer Wahl mit date (1) aus.
quelle
Ich bin kein Unix-Typ, aber ich denke, Sie können verwenden
quelle
quelle
Hier ist meine awk-Lösung (von einem Windows / XP-System mit MKS-Tools, die im Verzeichnis C: \ bin installiert sind). Es ist so konzipiert, dass das aktuelle Datum und die aktuelle Uhrzeit in der Form mm / dd hh: mm am Anfang jeder Zeile hinzugefügt werden, nachdem dieser Zeitstempel beim Lesen jeder Zeile aus dem System abgerufen wurde. Sie können natürlich das BEGIN-Muster verwenden, um den Zeitstempel einmal abzurufen und diesen Zeitstempel jedem Datensatz hinzuzufügen (egal). Ich habe dies getan, um eine Protokolldatei, die zum Zeitpunkt der Erstellung der Protokollnachricht generiert wurde, mit dem Zeitstempel zu kennzeichnen.
/"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), die in der Eingabezeile abgeglichen werden sollen, und optional, wenn Sie alle Eingabezeilen abgleichen möchten.
Dies sollte auch auf Linux / UNIX-Systemen funktionieren. Entfernen Sie einfach das C \: \\ bin \\ und verlassen Sie die Leitung
Dies setzt natürlich voraus, dass Sie mit dem Befehl "Datum" zum Standardbefehl zum Anzeigen / Festlegen von Linux / UNIX-Datumsangaben ohne spezifische Pfadinformationen gelangen (dh Ihre Umgebungs-PATH-Variable ist korrekt konfiguriert).
quelle
Mischen Sie einige Antworten von natevw und Frank Ch. Eigler.
Es hat Millisekunden, ist leistungsfähiger als
date
jedes Mal ein externer Befehl aufzurufen, und Perl ist auf den meisten Servern zu finden.Alternative Version mit Flush und Read in einer Schleife:
quelle
printf "%s+%06d %s", (strftime "%Y-%m-%dT%H:%M:%S", gmtime($s)), $ms, $_;
Sie können dies tun (mit gnu / sed ):
Beispiel:
Natürlich können Sie auch andere Optionen des Programms verwenden Datum . Ersetzen
date +%T
Sie einfach durch das, was Sie brauchen.quelle
Die Antwort von caerwyn kann als Unterprogramm ausgeführt werden, wodurch die neuen Prozesse pro Zeile verhindert werden:
quelle
date
es in jeder Zeile erzeugt wird?timestamp() { while read line; do echo "$(date) $line"; done; }; export -f timestamp
in einem Skript, das Sie als Quelle verwenden.date
Verwenden Sie Bashprintf
im % (Datespec) T- Format , um zu verhindern, dass für jede Zeile ein Laichbefehl ausgeführt wird . So kann es aussehentimestamp() { while IFS= read -r line; do printf "%(%F %T)T %s\n" -1 "$line"; done; }
. Shell-Buildins werden nicht erzeugt. Datespec Format ist wiestrftime(3)
zBdate
Formate. Dies erfordert Bash, nicht sicher, seit welcher Version es diesenprintf
Bezeichner unterstützt .Haftungsausschluss : Die von mir vorgeschlagene Lösung ist kein in Unix integriertes Dienstprogramm.
Ich hatte vor ein paar Tagen ein ähnliches Problem. Die Syntax und die Einschränkungen der oben genannten Lösungen haben mir nicht gefallen, daher habe ich in Go schnell ein Programm zusammengestellt, um die Arbeit für mich zu erledigen.
Sie können das Tool hier überprüfen: Preftime
Im Abschnitt " Releases " des GitHub-Projekts befinden sich vorgefertigte ausführbare Dateien für Linux, MacOS und Windows .
Das Tool verarbeitet unvollständige Ausgabezeilen und hat (aus meiner Sicht) eine kompaktere Syntax.
<command> | preftime
Es ist nicht ideal, aber ich denke, ich würde es teilen, falls es jemandem hilft.
quelle
mache es mit
date
undtr
undxargs
unter OSX:Wenn Sie Millisekunden wollen:
Beachten Sie jedoch, dass das Datum unter OSX nicht die Option% N bietet. Sie müssen also gdate (
brew install coreutils
) installieren, um schließlich zu folgendem Ergebnis zu gelangen:quelle
Wenn der Wert, den Sie voranstellen, in jeder Zeile gleich ist, starten Sie Emacs mit der Datei.
Ctrl + <space>
Scrollen Sie am Anfang der Datei (um diese Stelle zu markieren) bis zum Anfang der letzten Zeile (Alt +> geht zum Ende der Datei ... was wahrscheinlich auch die Umschalttaste und dann Strg betrifft + a, um an den Anfang dieser Zeile zu gelangen) und:
Ctrl + x r t
Mit diesem Befehl können Sie das gerade angegebene Rechteck einfügen (ein Rechteck mit einer Breite von 0).
2008-8-21 6:45 PM <enter>
Oder was auch immer Sie voranstellen möchten ... dann sehen Sie diesen Text vor jeder Zeile innerhalb des Rechtecks mit der Breite 0.
UPDATE: Ich habe gerade festgestellt, dass Sie nicht das gleiche Datum möchten, daher funktioniert dies nicht ... obwohl Sie dies möglicherweise in Emacs mit einem etwas komplizierteren benutzerdefinierten Makro tun können, ist diese Art der Rechteckbearbeitung dennoch möglich ziemlich schön zu wissen über ...
quelle