Рассчитать разницу во времени из разных столбцов - Баш - PullRequest
0 голосов
/ 17 декабря 2018

Я видел много ответов, но ни один не решил мою проблему.Вот мой штраф

cat run_time
Done  City        Start_time              End_time  
Yes   Chicago     10:16:51,14-Dec-2018   10:19:38,14-Dec-2018        
Yes   Atlanta     10:12:58,14-Dec-2018   10:20:58,14-Dec-2018               
No    Minnetonka  10:16:38,14-Dec-2018   10:21:50,14-Dec-2018        
Yes   Hopkins     10:22:20,14-Dec-2018   10:18:11,14-Dec-2018

Когда я могу вычислить вручную, все работает.

TO=$(date -d "10:16:58 14-Dec-2018" +%s)
TAL=$(date -d "10:16:50 14-Dec-2018" +%s)
TOTAL=$(( "$TO" - "$TAL" ))
echo $TOTAL
8

Однако я получаю сообщение об ошибке всякий раз, когда я пытаюсь интегрироватьв функцию awk.

Сначала я удалил запятую между временем и датой.

sed -i -e 's/,/ /g' run_time
Done  City        Start_time              End_time  
Yes   Chicago     10:16:51 14-Dec-2018   10:19:38 14-Dec-2018                
Yes   Atlanta     10:12:58 14-Dec-2018   10:20:58 14-Dec-2018               
No    Minnetonka  10:16:38 14-Dec-2018   10:21:50 14-Dec-2018        
Yes   Hopkins     10:22:20 14-Dec-2018   10:18:11 14-Dec-2018

При запуске следующей команды awk отобразится информация:

awk 'BEGIN { OFS = "\t" } NR == 1 { $7 = "Time_diff" } NR >= 2 { $7 = "$3,$4" - "$5,$6" } 1' < run_time|column -t
Done  City        Start_time              End_time               Time_diff
Yes   Chicago     10:16:51 14-Dec-2018  10:19:38 14-Dec-2018  
Yes   Atlanta     10:12:58 14-Dec-2018  10:20:58 14-Dec-2018  
No    Minnetonka  10:16:38 14-Dec-2018  10:21:50 14-Dec-2018  
Yes   Hopkins     10:22:20 14-Dec-2018  10:18:11 14-Dec-2018  

Моя цель - вычислить разницу во времени и добавить в поле Time_diff

.

Ответы [ 5 ]

0 голосов
/ 19 декабря 2018

Использование основных модулей Perl

> cat kwa_time.in
Done  City        Start_time              End_time
Yes   Chicago     10:16:51,14-Dec-2018   10:19:38,14-Dec-2018
Yes   Atlanta     10:12:58,14-Dec-2018   10:20:58,14-Dec-2018
No    Minnetonka  10:16:38,14-Dec-2018   10:21:50,14-Dec-2018
Yes   Hopkins     10:22:20,14-Dec-2018   10:18:11,14-Dec-2018
> cat ./time_diff.sh
perl  -lane '
BEGIN {
use POSIX;
use Time::Local;
@months = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
}
print "$_\tTime_diff" if $.==1;
if($.>1)
{
$dte="$F[-1]";
$dts="$F[-2]";
$dte=~s/(\d+):(\d+):(\d+),(\d+)-(\S+)-(\d+)/timelocal($3,$2,$1,$4,(grep { $5 eq $months[$_] } 0..$#months)[0],$6-1900)/ge;
$dts=~s/(\d+):(\d+):(\d+),(\d+)-(\S+)-(\d+)/timelocal($3,$2,$1,$4,(grep { $5 eq $months[$_] } 0..$#months)[0],$6-1900)/ge;
$diff = abs($dte-$dts);
$hd=int $diff/3600;
$md=int (($diff-($hd*3600))/60);
$sd=int ($diff - ($hd*3600+$md*60));
printf("%s %02d:%02d:%02d\n",join(" ",@F),$hd,$md,$sd);
}
' $1
> ./time_diff.sh kwa_time.in | column -t
Done  City        Start_time            End_time              Time_diff
Yes   Chicago     10:16:51,14-Dec-2018  10:19:38,14-Dec-2018  00:02:47
Yes   Atlanta     10:12:58,14-Dec-2018  10:20:58,14-Dec-2018  00:08:00
No    Minnetonka  10:16:38,14-Dec-2018  10:21:50,14-Dec-2018  00:05:12
Yes   Hopkins     10:22:20,14-Dec-2018  10:18:11,14-Dec-2018  00:04:09
>
0 голосов
/ 17 декабря 2018

idk, что означает, что время окончания должно быть раньше, чем время начала, но это с использованием GNU awk для функций времени указывает его на выходе с лидирующим знаком "-" на разнице времени:

$ cat tst.awk
BEGIN { OFS="\t" }
NR==1 {
    print $0, "Time_diff"
    next
}
{
    for (i=NF-1; i<=NF; i++) {
        split($i,t,/[:,-]/)
        t[5] = (index("JanFebMarAprMayJunJulAugSepOctNovDec",t[5])+2)/3
        secs[i] = mktime(t[6]" "t[5]" "t[4]" "t[1]" "t[2]" "t[3])
    }

    sign = " "
    totSecsDiff = secs[NF] - secs[NF-1]
    if (totSecsDiff < 0) {
        sign = "-"
        totSecsDiff = 0 - totSecsDiff
    }

    hrsDiff  = int(totSecsDiff / (60*60))
    minsDiff = int((totSecsDiff - (hrsDiff*60*60)) / 60)
    secsDiff = totSecsDiff - (hrsDiff*60*60 + minsDiff*60)
    hmsDiff  = sprintf("%s%02d:%02d:%02d",sign,hrsDiff,minsDiff,secsDiff)

    print $0, hmsDiff
}

$ awk -f tst.awk file
Done  City        Start_time              End_time      Time_diff
Yes   Chicago     10:16:51,14-Dec-2018   10:19:38,14-Dec-2018    00:02:47
Yes   Atlanta     10:12:58,14-Dec-2018   10:20:58,14-Dec-2018    00:08:00
No    Minnetonka  10:16:38,14-Dec-2018   10:21:50,14-Dec-2018    00:05:12
Yes   Hopkins     10:22:20,14-Dec-2018   10:18:11,14-Dec-2018   -00:04:09
0 голосов
/ 17 декабря 2018

с использованием gawk (не posix, у которого нет функции времени)

Код самообъяснения

awk '
   function convert2time ( ArgStrHr ) {
      # mktime format used "YYYY MM DD HH MM SS [DST]"
      # time format provided "10:16:51,14-Dec-2018"
      # extract element in a array
      T=split( ArgStrHr, aElt, /[-: ,]/ )

      # return the conversion
      return mktime( sprintf( "%4d %2d %2d %2d %2d %2d", aElt[6], aMonth[ aElt[5] ], aElt[4], aElt[1], aElt[2], aElt[3] ) )
      }

   BEGIN {
      # For string month convertion used in convert function
      split( "Jan Fev Mar Apr May Jun Jul Aug Sep Oct Nov Dec", aTemp )
       # revert a[i]="month" in a["month"]=i
      for ( Idx in aTemp ) aMonth[ aTemp[ Idx] ] = Idx
      }

   FNR==1 { $(NF + 1) = "Difference" }

   FNR!=1 {
      # take time in coutable form
      T1 = convert2time( $3 )
      T2 = convert2time( $4 )
      # add a field with difference
      $(NF + 1) =  T2 - T1
      }

   # print lines
   1    
   ' YourFile
0 голосов
/ 17 декабря 2018
$ cat input.txt 
Done  City        Start_time              End_time  
Yes   Chicago     10:16:51,14-Dec-2018   10:19:38,14-Dec-2018        
Yes   Atlanta     10:12:58,14-Dec-2018   10:20:58,14-Dec-2018               
No    Minnetonka  10:16:38,14-Dec-2018   10:21:50,14-Dec-2018        
Yes   Hopkins     10:22:20,14-Dec-2018   10:18:11,14-Dec-2018



$ cat diff_time.awk
BEGIN{
    print "Done City Start_time End_time Time_diff"
}
{
    if(!/^Do/){
        diff_time=0
        start_full=substr($3,1,8)" "substr($3,10,11)
        end_full=substr($4,1,8)" "substr($4,10,11)
        "date -d "q start_full q" +%s"|getline start_epoc
        "date -d "q end_full q" +%s"|getline end_epoc
        diff_time= end_epoc - start_epoc
        if(diff_time<0){
            diff_time=diff_time*-1
        }
        "date -d@"diff_time" -u +%H:%M:%S"|getline diff_h
        print $0,diff_h
        }
}



$ awk -v q='"' -f diff_time.awk input.txt |column -t
Done  City        Start_time            End_time              Time_diff
Yes   Chicago     10:16:51,14-Dec-2018  10:19:38,14-Dec-2018  00:02:47
Yes   Atlanta     10:12:58,14-Dec-2018  10:20:58,14-Dec-2018  00:08:00
No    Minnetonka  10:16:38,14-Dec-2018  10:21:50,14-Dec-2018  00:05:12
Yes   Hopkins     10:22:20,14-Dec-2018  10:18:11,14-Dec-2018  00:04:09
0 голосов
/ 17 декабря 2018

Небольшой скрипт может сделать это

#!/bin/bash
(
TOTAL=0
while read -r line
do
  if [ "`echo $line|grep ^Done`" != "" ]
  then
    echo "$line"
  else
    TO=$(date -d "`echo $line|tr -s " "|cut -d " " -f 3|tr "," " "`" +%s)
    TAL=$(date -d "`echo $line|tr -s " "|cut -d " " -f 4|tr "," " "`" +%s)
    SUBTOTAL=$(( $TO - $TAL ))
    echo "$line $SUBTOTAL"
    TOTAL=$(( $TOTAL + $SUBTOTAL ))
  fi
done
echo $TOTAL
) <run_time

Объяснение: скрипт читает каждую строку run_time в переменную line.Строка, начинающаяся с Done, печатается просто (первая строка таблицы).Для всех остальных строк вы исключаете двойные пробелы (tr -s " "), извлекаете третье (cut -d " " -f 3) или четвертое (cat -d " " -f 4) поле, затем подставляете , на и используете ту же формулуВы дали вычислить даты начала / окончания и разницу.Наконец вы печатаете разницу рядом со строкой.В то же время вы сохраняете в сумме TOTAL сумму всех различий и распечатываете ее в конце.

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