Вычитание времени в строках, используя awk, perl или другой однострочник
Подскажите, пожалуйста, каким способом можно решить следующую задачу с помощью однострочника?
Задача в том, чтобы вычитать значение из первого столбца предыдущей стройки из первого столбца текущей строки и помещать его перед текущей строкой.
Есть файл, вида:
$ cat blabla
13:06:27.578195 blablabla
13:06:27.578243 bla bla
13:06:27.578271 bla
13:06:27.578337 zzz
13:06:27.578372 zzz zzz zzz
13:06:27.578372 zzz zzz zzz
13:07:02.224100 aaa bbb ccc
Необходимо, используя любую команду(ы) в одну строку получить вывод вида:
0 13:06:27.578195 blablabla
0.000048 13:06:27.578243 bla bla
0.000028 13:06:27.578271 bla
0.000066 13:06:27.578337 zzz
0.000035 13:06:27.578372 zzz zzz zzz
34,645728 13:07:02.224100 aaa bbb ccc
Кажется, что это можно сделать с помощью awk, но у меня не получилось.
Ответы (2 шт):
Не лишенный недостатков, но все же способ
$ perl -ane '$c = `date +%s.%N -d $F[0]`; printf "%.6f %s", $c - ($p or $c), $_; $p = $c' < log.txt
0.000000 13:06:27.578195 blablabla
0.000048 13:06:27.578243 bla bla
0.000028 13:06:27.578271 bla
0.000066 13:06:27.578337 zzz
0.000035 13:06:27.578372 zzz zzz zzz
0.000000 13:06:27.578372 zzz zzz zzz
34.645728 13:07:02.224100 aaa bbb ccc
Имейте в виду, что на границе суток смещение получится отрицательным.
например, с помощью программы gnu/awk.
разбиваем первое слово на части по разделителю :, преобразуем минуты-часы в секунды (умножая последовательно на 60).
если полученное значение меньше предыдущего, предполагаем, что это новые сутки, и вычитаем из предыдущего значения количество секунд в сутках.
awk 'BEGIN{ p = 0 }
{
split($1, a, ":");
s = 0;
for (i = 1; i <= length(a); i++) {
s = s * 60 + a[i]
};
if (p == 0) {
printf "0 "
} else {
if (p > s) {
p = p - 60 * 60 * 24;
}
printf "%.6f ", s - p
};
p = s;
print $0
}'
из набора данных:
13:06:27.578195 blablabla
13:06:27.578243 bla bla
13:06:27.578271 bla
13:06:27.578337 zzz
13:06:27.578372 zzz zzz zzz
13:06:27.578372 zzz zzz zzz
13:07:02.224100 aaa bbb ccc
01:07:02.224109 новый день
получается такой:
0 13:06:27.578195 blablabla
0.000048 13:06:27.578243 bla bla
0.000028 13:06:27.578271 bla
0.000066 13:06:27.578337 zzz
0.000035 13:06:27.578372 zzz zzz zzz
0.000000 13:06:27.578372 zzz zzz zzz
34.645728 13:07:02.224100 aaa bbb ccc
43200.000009 01:07:02.224109 новый день
чтобы получить однострочник, просто убираем все пробелы (кроме как в аргументе функции printf) и новые строки:
awk 'BEGIN{p=0}{split($1,a,":");s=0;for(i=1;i<=length(a);i++){s=s*60+a[i]};if(p==0){printf"0 "}else{if(p>s){p=p-60*60*24;}printf"%.6f ",s-p};p=s;print$0}'