linux - 找出三个时间戳之间的差异,这三个时间戳不是日期命令接受的格式

标签 linux bash date unix awk

我有一个包含三个不同时间戳的文件,如下所示。 (我只是在这里放了两行。该文件有数千行这样的行。)

blah!blah!20190206 12:59:03:579 PM!blah!20190206 12:59:03:691 PM!blah!20190206 12:59:06:422 PM!blah!blah
blah!blah!20190206 12:59:06:510 PM!blah!20190206 12:59:06:534 PM!blah!20190206 12:59:06:928 PM!blah!blah

我试图找出每一行中每个时间戳之间的差异。

使用下面的 awk 命令,

awk -F! 'BEGIN{OFS="!";} {print $3, $5, $7}' | columnt -t -s "!"

我可以像下面这样提取时间戳。

20190206 12:59:03:579 PM  20190206 12:59:03:691 PM  20190206 12:59:06:422 PM
20190206 12:59:06:510 PM  20190206 12:59:06:534 PM  20190206 12:59:06:928 PM

现在,首先问题是这些时间戳的格式不适合传递给 date 命令。

$ date -d "20190206 12:59:06:510 PM" +%s
date: invalid date '20190206 12:59:06:510 PM'
$ date -d "20190206 12:59:06,510 PM" +%s+%3N
1550080746+510
$
$ date -d "20190206 12:59:06,536 PM" +%s+%3N
1550080746+536
$
$ echo $(( `date -d "20190206 12:59:06,510 PM" +%s+%3N` - `date -d "20190206 12:59:06,536 PM" +%s+%3N` ))
$ 1046
$

第三个冒号需要用逗号替换才能传递给日期命令。

其次,我如何获得如下所示的输出,其中每行中的时间戳与时间戳一起打印出来。因此,我可以浏览输出并找出哪一行花费了更多时间。

20190206 12:59:03:579 PM  20190206 12:59:03:691 PM  20190206 12:59:06:422 PM 
 (difference between first and second column)  (difference between second and third column)
20190206 12:59:06:510 PM  20190206 12:59:06:534 PM  20190206 12:59:06:928 PM 
 (difference between first and second column)  (difference between second and third column)

20190206 12:59:03:579 PM  20190206 12:59:03:691 PM  20190206 12:59:06:422 PM 
 112 milliseconds  2731 milliseconds
20190206 12:59:06:510 PM  20190206 12:59:06:534 PM  20190206 12:59:06:928 PM 
 24 milliseconds 394 milliseconds

最佳答案

如果 date 无法读取输入,请使用 sed 将输入格式化为它可以读取的格式。

cat <<EOF >file
blah!blah!20190206 12:59:03:579 PM!blah!20190206 12:59:03:691 PM!blah!20190206 12:59:06:422 PM!blah!blah
blah!blah!20190206 12:59:06:510 PM!blah!20190206 12:59:06:534 PM!blah!20190206 12:59:06:928 PM!blah!blah
EOF

# remove the blah! words to leave only timestamps
# so we have: '20190206 12:59:03:579 PM!20190206 12:59:03:691 PM!20190206 12:59:06:422 PM'
<file cut -d'!' -f3,5,7 
# substitute the parts ':123 ' into '.123 ' so that date knows it's miliseconds
# now we have '20190206 12:59:03.579 PM!20190206 12:59:03.691 PM!20190206 12:59:06.422 PM'
sed 's/:\([0-9]\{3\} \)/.\1/g' |
# read the dates - they are still separated by `!`
while IFS='!' read -r d1 d2 d3; do
    # convert dates into seconds since epoch
    s1=$(date --date="$d1" +%s.%N)
    s2=$(date --date="$d2" +%s.%N)
    s3=$(date --date="$d3" +%s.%N)
    # compute differences
    diff21=$(bc <<<"scale=100; $s2 - $s1")
    diff32=$(bc <<<"scale=100; $s3 - $s2")
    # nice looking printf - I leave it to OP to extract only miliseconds and such
    printf "%.3f %.3f\n" "$diff21" "$diff32"

done

将输出:

0.112 2.731
0.024 0.394

最后,我很喜欢 xargs,这里使用 xargs 也是一样的:

<file cut -d'!' -f3,5,7 | 
sed 's/:\([0-9]\{3\} \)/.\1/g' |
# substitute `!` for a newline
tr '!' '\n' | 
# run date on each input line converting to seconds
xargs -i date --date={} +%s.%N |
# prepare for bc
xargs -n3 sh -c 'printf "%s-%s\n%s-%s\n" "$2" "$1" "$3" "$2"' -- |
# compute differences for each line
xargs -n1 sh -c 'bc <<<"$@"' -- |
# nice looking printf
xargs -n2 printf -- "%.3f %.3f\n"

看起来更整洁。

关于linux - 找出三个时间戳之间的差异,这三个时间戳不是日期命令接受的格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54689105/

相关文章:

c - 父进程在设置 SIGCHLD 时被阻塞

linux - 预定的 cron 作业不工作

java - Swing 程序中的标准输出会怎样?

bash - sed 不删除通配符

bash - ( ... ) 和 { ... } 如何与 bash 中的管道创建子 shell 进行交互?

mysql - 如何计算两个日期之间的天数,

c 多个源文件返回错误值

python - Airflow 中的动态任务定义

sql - HQL 选择使用日期作为标准错误

python - 以日期和第三个变量作为颜色的散点图