標準入力にタイムスタンプを付加する Unix ユーティリティはありますか?

StackOverflow https://stackoverflow.com/questions/21564

  •  09-06-2019
  •  | 
  •  

質問

結局、このための簡単なスクリプトを Python で作成しましたが、テキストを入力して各行の先頭にテキスト (私の場合はタイムスタンプ) を追加できるユーティリティはないかと考えていました。理想的には、次のような使用法になります。

cat somefile.txt | prepend-timestamp

(sed に答える前に、これを試してみました:

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

ただし、これでは date コマンドが sed の実行時に 1 回しか評価されないため、同じタイムスタンプが誤って各行の先頭に付加されます。)

役に立ちましたか?

解決

使ってみてはいかがでしょうか awk:

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

次のことを確認する必要があるかもしれません <command> ラインバッファされた出力を生成します。つまり、各行の後に出力ストリームをフラッシュします。タイムスタンプ awk 加算値は、行の終わりが入力パイプに現れた時刻になります。

awk でエラーが表示された場合は、試してください gawk その代わり。

他のヒント

ts から もっと見る 入力のすべての行の先頭にタイムスタンプが追加されます。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

注釈を付ける, 、そのリンクから、または 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

これはどう?

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

ライブ タイムスタンプを取得したいという要望から判断すると、ログ ファイルか何かに対してライブ更新を実行したいのではないでしょうか?多分

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

これをそこに投げるつもりです:には 2 つのユーティリティがあります デーモンツール 呼ばれた tai64n そして tai64nlocal これは、ログメッセージの前にタイムスタンプを追加するために作成されます。

例:

cat file | tai64n | tai64nlocal

Kieron の答えはこれまでのところ最良のものです。最初のプログラムがバッファリングしているために問題が発生する場合は、バッファリング解除プログラムを使用できます。

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

ほとんどの Linux システムにはデフォルトでインストールされます。自分でビルドする必要がある場合は、expect パッケージの一部です

http://expect.nist.gov

read(1) コマンドを使用して標準入力から一度に 1 行を読み取り、date(1) を使用して選択した形式で先頭に日付を付けた行を出力します。

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

私は Unix の専門家ではありませんが、使用できると思います

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

これが私の awk ソリューションです (MKS ツールが C:\bin ディレクトリにインストールされている Windows/XP システムからのもの)。これは、各行が読み取られるときにシステムからタイムスタンプを取得し、各行の先頭に現在の日付と時刻を mm/dd hh:mm の形式で追加するように設計されています。もちろん、BEGIN パターンを使用してタイムスタンプを 1 回フェッチし、そのタイムスタンプを各レコードに追加することもできます (すべて同じです)。これは、標準出力に生成されるログ ファイルに、ログ メッセージが生成された時点のタイムスタンプをタグ付けするために実行しました。

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

ここで、「pattern」は入力行で照合する文字列または正規表現 (引用符なし) で、すべての入力行と照合する場合はオプションです。

これは Linux/UNIX システムでも機能するはずです。行から C\:\\bin\\ を削除するだけです。

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

もちろん、これは、コマンド「date」により、特定のパス情報なしで標準の Linux/UNIX 日付表示/設定コマンドが表示される (つまり、環境 PATH 変数が正しく設定されている) ことを前提としています。

上記の回答をいくつか混ぜ合わせます ナテブウ そしてフランク・C.アイグラー。

ミリ秒があり、外部メソッドを呼び出すよりもパフォーマンスが優れています。 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);
  }'
$ cat somefile.txt | sed "s/^/`date`/"

これを行うことができます( ヌー/セド):

$ 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

免責事項:私が提案している解決策は Unix 組み込みユーティリティではありません。

数日前にも同様の問題に直面しました。私は上記のソリューションの構文と制限が気に入らなかったので、すぐに Go でその仕事を行うプログラムを組み立てました。

ここでツールを確認できます。 プレフタイム

Linux、MacOS、および Windows 用の事前に構築された実行可能ファイルが含まれています。 リリース GitHub プロジェクトのセクション。

このツールは不完全な出力行を処理し、(私の観点からすると) よりコンパクトな構文を備えています。

<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 + <スペース>

ファイルの先頭で (その位置をマークするため)、最後の行の先頭まで下にスクロールします (Alt + > でファイルの末尾に移動します...)これにはおそらく Shift キーも必要で、次に Ctrl + a を押してその行の先頭に移動します)。

Ctrl + バツ r t

これは、指定した四角形 (幅 0 の四角形) に挿入するコマンドです。

2008-8-21 6:45PM <入力>

または、先頭に追加したいものは何でも...幅 0 の四角形内のすべての行の先頭にテキストが追加されていることがわかります。

アップデート:同じ日付を望まないことに今気づきました。そのため、これは機能しません...emacs では、もう少し複雑なカスタム マクロを使用してこれを実行できるかもしれませんが、それでも、この種の四角形編集について知っておくと非常に役立ちます...

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top