Найти разницу между тремя временными метками, которые не в формате, который принимает команда даты - PullRequest
0 голосов
/ 14 февраля 2019

У меня есть файл с тремя разными временными метками, как показано ниже.(Я только что поместил здесь две строки. Файл имеет тысячи таких строк.)

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
$

Третий двоеточие необходимо заменить на запятую, чтобы передать команде date.

Во-вторых, как получить вывод, как показано ниже, с помощью командыразница между временными метками в каждой строке, напечатанными вместе с временными метками.Итак, я могу просмотреть вывод и найти, какая строка заняла больше времени.

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

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

С GNU awk для функций времени:

$ cat tst.awk
BEGIN { FS="!"; OFS="  " }
{
    numTs = 0
    for (i=3; i<=7; i+=2) {
        split($i,t,/[[:space:]:]/)

        date = gensub(/(.{4})(.{2})/,"\\1 \\2 ",1,t[1])
        time = ( t[2] + ( (t[6] == "PM") && (t[2] < 12) ? 12 : 0 ) ) " " t[3] " " t[4]
        secs = mktime(date " " time)

        ts[++numTs] = $i
        ms[numTs] = (secs * 1000) + t[5]
    }
    print ts[1], ts[2], ts[3]
    print " " (ms[2] - ms[1]) " milliseconds", (ms[3] - ms[2]) " milliseconds"
}

$ awk -f tst.awk file
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
0 голосов
/ 14 февраля 2019

Если 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"

, и это выглядит аккуратнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...