回答:
使用してみてくださいawk
:
<command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; fflush(); }'
が<command>
ラインバッファリングされた出力を生成することを確認する必要がある場合があります。タイムスタンプがawk
追加されるのは、行の終わりが入力パイプに表示された時間です。
awkがエラーを表示する場合は、gawk
代わりに試してください。
gawk
場合、の代わりにそれをインストールして使用する必要がありますawk
。MacPortsを使用している場合:sudo port install gawk
awk
のstrftime()
ミリ秒の精度はありません。ただし、date
コマンドは使用できます。基本的には、ナノ秒を3文字にトリミングするだけです。次のようになりますCOMMAND | while read -r line; do echo "$(date '+%Y-%m-%d %T.%3N') $line"; done
。%H:%M:%Sは%Tで省略できることに注意してください。あなたはまだ使用したい場合はawk
、いくつかの理由で、次の操作を行うことができます:COMMAND | awk '{ "date +%Y-%m-%d\\ %T.%3N" | getline timestamp; print timestamp, $0; fflush(); }'
ts
moreutilsからは、入力するすべての入力行にタイムスタンプを付加します。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
$
それをインストールするには:
sudo apt-get install moreutils
bad command 2>&1 | ts
結果はJan 29 19:58:31 -bash: bad: command not found
2014 Mar 21 18:07:28
。どうすれば入手できますか?
brew install moreutils
。UTCを出力するには、TZをローカルに設定できます。例ls -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'
annotate、そのリンクを介して、またはannotate-output
Debian devscripts
パッケージと同様に利用できます。
$ 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
与えられた答えを可能な限り単純なものに蒸留します:
unbuffer $COMMAND | ts
Ubuntuでは、expect-devおよびmoreutilsパッケージに含まれています。
sudo apt-get install expect-dev moreutils
expect
はそうexpect-dev
ではありませんが、後者は前者を引き込むので、これは機能します。(Ubuntu 14.10、バイナリが
expect-dev
unbuffer $COMMAND | ts -s %.s
(-s
経過時間および%.s
秒単位の時間の場合は小数部を使用)
これはどう?
cat somefile.txt | perl -pne 'print scalar(localtime()), " ";'
ライブタイムスタンプを取得したいという希望から判断すると、ログファイルなどでライブ更新を実行したい場合は、多分
tail -f /path/to/log | perl -pne 'print scalar(localtime()), " ";' > /path/to/log-with-timestamps
tail -f /path/to/log | perl -pne 'use POSIX qw(strftime); print strftime "%Y-%m-%dT%H:%M:%SZ ", gmtime();'
死霊のかぼちゃ1簡単なバージョンの利回りの代わりにISO8601 / RFC3339形式の日付を取得します。
BEGIN { $|++; }
は、Perlに出力を各行でフラッシュさせるために、printステートメントの前に追加すると役立つ場合があります。
ls | perl -pne 'print localtime." "'
ます。文字列の連結が原因でスカラー変換が行われます。
-p
と-n
オプションの両方を使用するのはなぜですか?のように思える-n
あなたが指定した場合に冗長です-p
。
メッセージをログに記録するためにタイムスタンプを前に付けるために作成されたtai64nおよびtai64nlocalと呼ばれる一対のユーティリティがdaemontoolsにあります。
例:
cat file | tai64n | tai64nlocal
キーロンの答えは今のところ最高です。最初のプログラムがバッファリングしているために問題が発生した場合は、unbufferプログラムを使用できます。
unbuffer <command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; }'
ほとんどのLinuxシステムにデフォルトでインストールされます。自分でビルドする必要がある場合は、expectパッケージの一部です
#! /bin/sh
unbuffer "$@" | perl -e '
use Time::HiRes (gettimeofday);
while(<>) {
($s,$ms) = gettimeofday();
print $s . "." . $ms . " " . $_;
}'
これが私のawkソリューションです(MKSツールがC:\ binディレクトリにインストールされているWindows / XPシステムから)。これは、現在の日付と時刻をmm / dd hh:mmの形式で、各行が読み取られるときにシステムからタイムスタンプをフェッチした各行の先頭に追加するように設計されています。もちろん、BEGINパターンを使用してタイムスタンプを1回フェッチし、そのタイムスタンプを各レコードに追加することもできます(すべて同じです)。これは、ログメッセージが生成されたときのタイムスタンプでstdoutに生成されているログファイルにタグを付けるために行いました。
/"pattern"/ "C\:\\\\bin\\\\date '+%m/%d %R'" | getline timestamp;
print timestamp, $0;
ここで、「パターン」は、入力行で照合する文字列または正規表現(引用符なし)であり、すべての入力行を照合する場合はオプションです。
これはLinux / UNIXシステムでも機能するはずです。C\:\\ bin \\を削除して、次の行を残してください。
"date '+%m/%d %R'" | getline timestamp;
もちろん、これは、コマンド「date」が特定のパス情報なしで標準のLinux / UNIXの日付表示/設定コマンドにアクセスできることを前提としています(つまり、環境のPATH変数が正しく構成されています)。
上記のいくつかの答えミキシングnatevwとフランク・Chのを。アイグラー。
ミリ秒で、date
毎回外部コマンドを呼び出すよりもパフォーマンスがよく、ほとんどのサーバーでperlを見つけることができます。
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);
'
フラッシュとループで読み取る代替バージョン:
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);
}'
printf "%s+%06d %s", (strftime "%Y-%m-%dT%H:%M:%S", gmtime($s)), $ms, $_;
$ cat somefile.txt | sed "s/^/`date`/"
これを行うことができます(gnu / sedを使用):
$ some-command | sed "x;s/.*/date +%T/e;G;s/\n/ /g"
例:
$ { echo 'line1'; sleep 2; echo 'line2'; } | sed "x;s/.*/date +%T/e;G;s/\n/ /g"
20:24:22 line1
20:24:24 line2
もちろん、プログラムの日付の他のオプションを使用できます。date +%T
必要なものに置き換えるだけです。
caerwynの回答はサブルーチンとして実行できます。これにより、行ごとの新しいプロセスが妨げられます。
timestamp(){
while read line
do
echo `date` $line
done
}
echo testing 123 |timestamp
date
すべての行でスポーンされるのを防ぎますか?
timestamp() { while read line; do echo "$(date) $line"; done; }; export -f timestamp
します。
date
すべての行でコマンドが生成されないようにするにはprintf
、%(datespec)T形式で組み込みのbashを使用してみてください。したがって、次のようになりtimestamp() { while IFS= read -r line; do printf "%(%F %T)T %s\n" -1 "$line"; done; }
ます。シェルのビルトインは生成されません。Datespec形式はstrftime(3)
ie date
形式に似ています。これにはbashが必要ですが、どのバージョンがそのprintf
指定子をサポートしているかは不明です。
免責事項:私が提案しているソリューションは、Unixの組み込みユーティリティではありません。
私は数日前に同様の問題に直面しました。上記のソリューションの構文と制限が気に入らなかったので、すぐにGoでプログラムを作成して、仕事をしました。
ここでツールを確認できます:preftime
GitHubプロジェクトのリリースセクションには、Linux、MacOS、Windows用のビルド済み実行可能ファイルがあります。
このツールは不完全な出力行を処理し、(私の観点から)よりコンパクトな構文を持っています。
<command> | preftime
理想的ではありませんが、誰かを助けるために共有したいと思います。
でそれをやってdate
とtr
してxargs
OSXに:
alias predate="xargs -I{} sh -c 'date +\"%Y-%m-%d %H:%M:%S\" | tr \"\n\" \" \"; echo \"{}\"'"
<command> | predate
ミリ秒が必要な場合:
alias predate="xargs -I{} sh -c 'date +\"%Y-%m-%d %H:%M:%S.%3N\" | tr \"\n\" \" \"; echo \"{}\"'"
ただし、OSXでは、dateでは%Nオプションが提供されないため、gdate(brew install coreutils
)をインストールする必要があるため、最終的には次のようになります。
alias predate="xargs -I{} sh -c 'gdate +\"%Y-%m-%d %H:%M:%S.%3N\" | tr \"\n\" \" \"; echo \"{}\"'"
先頭に追加する値がすべての行で同じである場合は、ファイルでemacsを起動してから、次のようにします。
Ctrl + <space>
(そのスポットをマークするために)ファイルの先頭でスクロールし、最後の行の先頭までスクロールします(Alt +>はファイルの最後に移動します...おそらくShiftキーも含まれ、次にCtrl + aでその行の先頭に移動)および:
Ctrl + x r t
これは、指定した長方形(幅0の長方形)に挿入するコマンドです。
2008-8-21 18:45 PM <Enter>
または、先頭に追加するものは何でも...すると、幅0の長方形内のすべての行の先頭にテキストが追加されます。
更新:同じ日付が必要ないことに気付いたので、これは機能しません...少し複雑なカスタムマクロを使用してemacsでこれを実行できる場合もありますが、このような長方形の編集は知ってかなりいい...
cat somefile.txt
「誤解を招く」ビット?私はそれが「一度に」起こり、単一のタイムスタンプを持つことを期待します。これはより良いテストプログラムではないでしょう(echo a; sleep 1; echo b; sleep 3; echo c; sleep 2)
か?