调整日志时间

时间:2014-12-01 14:39:07

标签: perl awk

这个日志是以格林威治标准时间记录的,所以我每天早上从它减去5个小时到达东部时间,并通过检查。

这是原始数据:

casper@casperbox:~$ tail /data/rafterman.log
115510.1 INFO log opened for 2014/12/01
115510.1 INFO successfully locked
115510.2 INFO starting
115510.2 INFO successfully set child death signal:
115510.2 INFO Env: 'PATH=/bin:/usr/bin'
115510.2 INFO Env: 'LD_LIBRARY_PATH='/
115510.2 INFO <- SYSSTATS
casper@casperbox:~$ tail /data/rafterman.log

我想知道这样的事情:

06:55 INFO log opened for 2014/12/01
06:55 INFO successfully locked
etc. 

我怎么能直接06:55 - 在小时和分钟之间放一个冒号的简单方法是什么? perl或awk one liner

casper@casperbox:~$ tail /data/rafterman.log | awk '{ $1 = $1 -50000; print } '
65510.1 INFO log opened for 2014/12/01  
65510.1 INFO successfully locked
65510.2 INFO starting
65510.2 INFO successfully set child death signal:
65510.2 INFO Env: 'PATH=/bin:/usr/bin'
65510.2 INFO Env: 'LD_LIBRARY_PATH='/
65510.2 INFO <- SYSSTATS
casper@casperbox:~$ tail /data/rafterman.log | awk '{ $1 = $1 -50000; print } '

4 个答案:

答案 0 :(得分:1)

怎么样

$ cat input
65510.1 INFO log opened for 2014/12/01  
65510.1 INFO successfully locked
65510.2 INFO starting
65510.2 INFO successfully set child death signal:
65510.2 INFO Env: 'PATH=/bin:/usr/bin'
65510.2 INFO Env: 'LD_LIBRARY_PATH='/
65510.2 INFO <- SYSSTATS

$ awk  '{sub("[0-9]{2}.[0-9]$", "", $1); sub("[0-9]{2}$", ":&",$1)}1' input
6:55 INFO log opened for 2014/12/01
6:55 INFO successfully locked
6:55 INFO starting
6:55 INFO successfully set child death signal:
6:55 INFO Env: 'PATH=/bin:/usr/bin'
6:55 INFO Env: 'LD_LIBRARY_PATH='/
6:55 INFO <- SYSSTATS

答案 1 :(得分:1)

$ perl -pe's/^(\d{1,2})(\d{2})\d{2}/sprintf("%02d:%s", $1-5, $2)/e' log
06:55.1 INFO log opened for 2014/12/01
06:55.1 INFO successfully locked
06:55.2 INFO starting
06:55.2 INFO successfully set child death signal:
06:55.2 INFO Env: 'PATH=/bin:/usr/bin'
06:55.2 INFO Env: 'LD_LIBRARY_PATH='/
06:55.2 INFO <- SYSSTATS

(也接受STDIN)


以下转换为当地时间。它甚至可以处理夏令时。

perl -MTime::Local=timegm -MPOSIX=strftime -pe'
   BEGIN { ($y,$m,$d)=(localtime)[6,5,4]; $y+=1900; $m+=1; }  # Guess

   ($y,$m,$d)=($1,$2,$3) if m{^\S+ INFO log opened for (\d+)/(\d+)/(\d+)};

   s/^(\d{1,2})(\d{2})(\d{2})/
      strftime("%H:%M", localtime(timegm($3,$2,$1,$d,$m-1,$y-1900)))
   /e;
'

在多伦多,它输出

06:55.1 INFO log opened for 2014/12/01
06:55.1 INFO successfully locked
06:55.2 INFO starting
06:55.2 INFO successfully set child death signal:
06:55.2 INFO Env: 'PATH=/bin:/usr/bin'
06:55.2 INFO Env: 'LD_LIBRARY_PATH='/
06:55.2 INFO <- SYSSTATS

在温哥华,它输出

03:55.1 INFO log opened for 2014/12/01
03:55.1 INFO successfully locked
03:55.2 INFO starting
03:55.2 INFO successfully set child death signal:
03:55.2 INFO Env: 'PATH=/bin:/usr/bin'
03:55.2 INFO Env: 'LD_LIBRARY_PATH='/
03:55.2 INFO <- SYSSTATS

如果.num是时间戳的一部分(例如几分之一秒),那么删除它所需要做的就是将\.\d+附加到模式中。 (这是我的两个解决方案的情况。)

答案 2 :(得分:0)

这就是你要求的:

$ awk '{$1=sprintf("%02d:%02d",substr($1,1,2)-5,substr($1,3,2))}1' file
06:55 INFO log opened for 2014/12/01
06:55 INFO successfully locked
06:55 INFO starting
06:55 INFO successfully set child death signal:
06:55 INFO Env: 'PATH=/bin:/usr/bin'
06:55 INFO Env: 'LD_LIBRARY_PATH='/
06:55 INFO <- SYSSTATS

但我不确定它实际上是什么,例如如果减去5个小时应该带你回到前一天。如果您确实需要在调整时间后调整日期,那么您需要的是GNU awk for gensub(),更重要的是时间函数:

$ cat tst.awk
/log opened/ { oldDate = gensub("/"," ","g",$NF) }
{
    oldTime = gensub(/(..?)(..)(..)\..*/,"\\1 \\2 \\3","",$1)
    oldSecs = mktime(oldDate " " oldTime)
    newSecs = oldSecs - (5 * 60 * 60)
    newDate = strftime("%Y/%m/%d",newSecs)
    newTime = strftime("%H:%M",newSecs)
}
/log opened/ { $NF = newDate }
{ $1 = newTime; print }

$ awk -f tst.awk file
06:55 INFO log opened for 2014/12/01
06:55 INFO successfully locked
06:55 INFO starting
06:55 INFO successfully set child death signal:
06:55 INFO Env: 'PATH=/bin:/usr/bin'
06:55 INFO Env: 'LD_LIBRARY_PATH='/
06:55 INFO <- SYSSTATS

如果您的时间戳为035510.2而不是115510.2,则会看到两个脚本之间的差异。

答案 3 :(得分:0)

这是来自A-TEAM的Mr.T。 而不是像傻瓜一样使用单行 - 为什么不将文件传输到perl脚本!!!!!

#!/usr/bin/perl
while (<>) {
    if ($_=~ /(^\d+\.\d+)Z/)    {
    my $new_time = $1 - 50000  ;
    my ($new_hour, $null) = split(/\./, $new_time);
    s/$1/$new_hour/g ;
    print $_ ;
    } 
}