使用bash脚本将文本转换为时间格式

时间:2019-03-20 11:11:58

标签: linux bash shell

我是Shell脚本的新手。我有一个制表符分隔的文件,例如

0018803 01  1710    2050    002571      
0018951 01  1934    2525    003277  
0019362 02  2404    2415    002829  
0019392 01  2621    2820    001924  
0019542 01  2208    2413    003434  
0019583 01  1815    2134    002971  

在这里,第3和第4列分别代表开始时间和结束时间。

我想在适当的timeFrame中转换这两列,以便我可以得到第6列,即第4列和第3列之间的精确时差,以小时和分钟为单位。

6列的结果将是3:405:5100:111:592:05

3 个答案:

答案 0 :(得分:2)

使用awk的一种方式:

$ cat test.awk
# create a function to split hour and minute
function f(h, x) {
    h[0] = substr(x,1,2)+0
    h[1] = substr(x,3,2)+0
}

{
    f(start, $3);
    f(end, $4);
    span  = end[1] - start[1] > 0 \
          ? sprintf("%d:%02d", end[0]-start[0], end[1]-start[1]) \
          : sprintf("%d:%02d", end[0]-start[0]-1, 60+end[1]-start[1]);
    print $0 OFS span
}

然后按以下方式运行awk文件:

$ awk -f test.awk input_file

编辑:根据@glenn jackman的建议,可以简化代码(请参阅@Kamil Cuk的方法):

function g(x) {
    return substr(x,1,2)*60 + substr(x,3,2)
}

{
    span = g($4) - g($3)
    printf("%s%s%d:%02d\n", $0, OFS, int(span/60), span%60)
}

答案 1 :(得分:2)

使用算术扩展的简单bash解决方案:

while IFS='' read -r l; do
        IFS=' ' read -r _ _ st et _ <<<"$l"
        d=$(( (10#${et:0:2} * 60 + 10#${et:2:2}) - (10#${st:0:2} * 60 + 10#${st:2:2}) ))
        printf "%s %02d:%02d\n" "$l" "$((d/60))" "$((d%60))"
done < intput_file_path

将输出:

0018803 01  1710    2050    002571   03:40
0018951 01  1934    2525    003277   05:51
0019362 02  2404    2415    002829   00:11
0019392 01  2621    2820    001924   01:59
0019542 01  2208    2413    003434   02:05
0019583 01  1815    2134    002971   03:19

答案 2 :(得分:1)

这是GNU awk中使用time functionsmktime转换为纪元时间和strftime将时间转换为所需格式HH:MM的人:

$ awk -v OFS="\t" '{
    dt3="1970 01 01 " substr($3,1,2) " " substr($3,3,2) " 00"
    dt4="1970 01 01 " substr($4,1,2) " " substr($4,3,2) " 00"
    print $0,strftime("%H:%M",mktime(dt4)-mktime(dt3),1)      # thanks @glennjackman,1 :)
}' file

输出(仅$ 6):

03:40
05:51
00:11
01:59
02:05
03:19