日期时间到纪元的转换

Datetime to epoch conversion

我有一个 bash 问题(使用 awk 时)。我正在提取文本文件中第一列和第五列的每个实例,并使用以下代码将其通过管道传输到新文件,

cut -f4 test170201.rawtxt | awk '/stream_0/ { print ,   }' > testLogFile.txt 

这是文件的一部分 (test170201.rawtxt) 我正在从 TimestampLoss

列中提取数据
Timestamp                 Stream     Status     Seq         Loss Bytes    Delay
17/02/01.10:58:25.212577  stream_0     OK      80281          0  1000     38473
17/02/01.10:58:25.213401  stream_0     OK      80282          0  1000     38472
17/02/01.10:58:25.215560  stream_0     OK      80283          0  1000     38473
17/02/01.10:58:25.216645  stream_0     OK      80284          0  1000     38472

这是我在 testLogFile.txt

中得到的结果
17/02/01.10:58:25.212577 0
17/02/01.10:58:25.213401 0
17/02/01.10:58:25.215560 0
17/02/01.10:58:25.216645 0

但是,我希望 Timestamp 在上面的文件中以纪元写入。有没有一种简单的方法可以修改我已经必须执行此操作的代码?

使用 GNU awk

输入

$ cat f
Timestamp                 Stream     Status     Seq         Loss Bytes    Delay
17/02/01.10:58:25.212577  stream_0     OK      80281          0  1000     38473
17/02/01.10:58:25.213401  stream_0     OK      80282          0  1000     38472
17/02/01.10:58:25.215560  stream_0     OK      80283          0  1000     38473
17/02/01.10:58:25.216645  stream_0     OK      80284          0  1000     38472

输出

$ awk '
BEGIN{cyear = strftime("%y",systime())}
function epoch(v,       datetime){
    sub(/\./," ",v);
    split(v,datetime,/[/: ]/); 
    datetime[1] = datetime[1] <= cyear ? 2000+datetime[1] : 1900+datetime[1];
    return mktime(datetime[1] " " datetime[2] " " datetime[3] " " datetime[4]" " datetime[5]" " datetime[6])
}
/stream_0/{
    print epoch(),
}' f



1485926905 0
1485926905 0
1485926905 0
1485926905 0

要写入新文件,只需像下面这样重定向

cut -f4 test170201.rawtxt | awk '
BEGIN{cyear = strftime("%y",systime());}
function epoch(v,       datetime){
    sub(/\./," ",v);
    split(v,datetime,/[/: ]/); 
    datetime[1] = datetime[1] <= cyear ? 2000+datetime[1] : 1900+datetime[1];
    return mktime(datetime[1] " " datetime[2] " " datetime[3] " " datetime[4]" " datetime[5]" " datetime[6])
}
/stream_0/{
    print epoch(),
}'  > testLogFile.txt

鉴于:

$ cat file
Timestamp                 Stream     Status     Seq         Loss Bytes    Delay
17/02/01.10:58:25.212577  stream_0     OK      80281          0  1000     38473
17/02/01.10:58:25.213401  stream_0     OK      80282          0  1000     38472
17/02/01.10:58:25.215560  stream_0     OK      80283          0  1000     38473
17/02/01.10:58:25.216645  stream_0     OK      80284          0  1000     38472

您可以编写 POSIX Bash 脚本来完成您要查找的内容:

while IFS= read -r line || [[ -n "$line" ]]; do
    if [[ "$line" =~ ^[[:digit:]]{2}/[[:digit:]]{2}/[[:digit:]]{2} ]]
    then
        arr=($line)
        ts=${arr[0]}
        dec=${ts##*.}   # fractional seconds
        # GNU date may need different flags:
        epoch=$(date -j -f "%y/%m/%d.%H:%M:%S" "${ts%.*}" "+%s")
        printf "%s.%s\t%s\n" "$epoch" "$dec" "${arr[4]}"
    fi  
    done <file >out_file

$ cat out_file
1485975505.212577   0
1485975505.213401   0
1485975505.215560   0
1485975505.216645   0

对于 GNU 日期,尝试:

while IFS= read -r line || [[ -n "$line" ]]; do
    if [[ "$line" =~ ^[[:digit:]]{2}/[[:digit:]]{2}/[[:digit:]]{2} ]]
    then
        arr=($line)
        ts="20${arr[0]}"
        d="${ts%%.*}"
        tmp="${ts%.*}"
        tm="${tmp#*.}"
        dec="${ts##*.}"    # fractional seconds
        epoch=$(date +"%s" --date="$d $tm" )
        printf "%s.%s\t%s\n" "$epoch" "$dec" "${arr[4]}"
    fi  
    done <file >out_file

对于 GNU awk 解决方案,您可以这样做:

awk 'function epoch(s){ 
                        split(s, dt, /[/:. ]/)
                        s="20" dt[1] " " dt[2] " " dt[3] " " dt[4] " " dt[5] " " dt[6]
                        return mktime(s) "." dt[7]} 
     /^[0-9][0-9]/      { print epoch(),  }'    file >out_file

如果您不希望纪元中包含小数秒,可以轻松将其删除。

awk -F '[.[:blank:]]+' '
   # use separator for dot and space (to avoid trailing time info)

   {
   # for line other than header
   if( NR>1) {
      # time is set for format "YYYY MM DD HH MM SS [DST]"
      #  prepare with valuable info
      T = "20" " " 
      # use correct separator
      gsub( /[\/:]/, " ", T)
      # convert to epoch
      E = mktime( T)

      # print result, adding fractionnal as mentionned later
      printf("%d.%d %s\n", E, , )
      }
     else {
        # print header (line 1)
        print  " "
        }
    }
   ' test170201.rawtxt \
   > Redirected.file
  • 自己评论,为了便于理解,代码较长
  • 使用 gnu awk 实现 mktime 功能在 posix 或旧版本
  • 中不可用

Oneliner 在这里做了一些优化

awk -F '[.[:blank:]]+' '{if(NR>1){T="20"" ";gsub(/[\/:]/," ", T);=mktime(T)}print " "}' test170201.rawtxt