web-dev-qa-db-ja.com

ログのタイムゾーンを調整しながら変換する方法

ログから日付スタンプの形式をリアルタイムで操作したいと思います。現在の形式は2016-04-06T23:19:20.878Zです。それをローカルタイムゾーンに変換し、ミリ秒を削除する可能性があります。 tail -fの出力をawksedのようなものにパイプして、残りの出力を変更せずにリアルタイムで実行できるようにすることはできますか?

5
emkman

タイムスタンプがどのフィールドにあるかがわかっている場合(たとえば、2番目の単語)、awkを使用してdateを呼び出すように変換を行うことができます。

_stdbuf -oL tail -f ... |
awk -v timefield=2 '{
  if($timefield ~ /[0-9].*Z/){
    "date --date \"" $timefield "\"" | getline tod
     sub($timefield,tod,$0)
  }
  print 
}'
_

上記の_stdbuf -oL_で示すように、パイプにバッファリングしないようにテールを取得する必要がある場合があります。フィールドがわからない場合、またはフィールドが移動する場合は、各単語のタイムゾーンパターンを一致させることができます。

_awk  '{
  for(timefield = 1;timefield<=NF;timefield++)
    if($timefield ~ /^[0-9].*T.*Z$/){
      "date --date \"" $timefield "\"" | getline tod
      sub($timefield,tod,$0)
    }
   print 
}'
_

これは、タイムスタンプが空白で区切られていることを前提としています。


_I2016-04-08T00:34:29.372Z]v3087_のコメントの例を使用すると、awkのsubstr(string,offset,length)を使用してタイムスタンプを抽出できます。これは、長さとオフセットが一定であるためです:datestamp = substr($timefield, 2, 24)。結果の出力で最初のIと末尾のコードを保持したくない場合は、次のようになります。

_awk -v timefield=1 '{
  if($timefield ~ /[0-9].*Z/){
     datestamp = substr($timefield, 2, 24)
    "date --date \"" datestamp "\"" | getline tod
     sub($timefield,tod,$0)
  }
  print 
}'
_

追加のコードを保持する場合は、subを変更して、フィールド全体ではなく日付スタンプ文字列を置き換えます。たとえば、追加のスペースsub(datestamp," " tod " ",$0)を使用します。

2
meuh