如何在日志中转换时区,因为它们被拖尾

emk*_*man 5 logs sed awk tail

我想从日志中实时操纵日期戳的格式,因为它正在被拖尾。当前格式为2016-04-06T23:19:20.878Z. 我想将其转换为我们的本地时区并可能删除毫秒。我可以将 的输出通过管道传输tail -f到类似的东西中awksed以便可以在输出的其余部分不变的情况下实时完成吗?

meu*_*euh 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 
}'
Run Code Online (Sandbox Code Playgroud)

您可能需要让 tail 不缓冲到管道,如上面所示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 
}'
Run Code Online (Sandbox Code Playgroud)

这假设您的时间戳由空格分隔。


使用 的注释中的示例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 
}'
Run Code Online (Sandbox Code Playgroud)

如果您想保留额外的代码,请更改sub以替换日期戳字符串而不是整个字段,例如使用额外的空格:sub(datestamp," " tod " ",$0)