결과

결과

파일 형식은 다음과 같습니다.

aaa 1-00:12:43.122
aaa 0-21:14:43.133
bbb 3-11:14:54.433
bbb 2-00:00:10

두 번째 열의 숫자는 형식입니다 d-hh:mm:ss.nnn. 어떤 경우에는 마지막 10진수 3자리가 존재하지 않습니다. 각 사용자의 총 지속 시간을 얻기 위해 첫 번째 열로 그룹화하여 합산하는 방법을 알아내려고 합니다. 따라서 이 예의 결과는 다음과 같습니다.

aaa 1-21:27:26.255
bbb 5-11:15:04.433

답변1

다음 awk스크립트를 사용하세요.

BEGIN {
   FS=" |-|:"
}
{
   data[$1][2]+=$2
   data[$1][3]+=$3
   data[$1][4]+=$4
   data[$1][5]+=$5
}
END {
   for( record in data ) {
      if( data[record][5]>=60 ) {
         data[record][4]+=1
         data[record][5]-=60.0
      }
      if( data[record][4]>=60 ) {
         data[record][3]+=1
         data[record][4]-=60
      }
      if( data[record][3]>=24 ) {
         data[record][2]+=1
         data[record][3]-=24
      }
      printf( "%s %d-%02.0f:%02.0f:%06.3f\n", record, data[record][2], data[record][3], data[record][4], data[record][5] )
   }
}

용법:

~/scratch/se/379631$ cat input
aaa 1-00:12:43.122
aaa 0-21:14:43.133
bbb 3-11:14:54.433
bbb 2-00:00:10
~/scratch/se/379631$ gawk -f 379631.awk input
aaa 1-21:27:26.255
bbb 5-11:15:04.433

답변2

AND perl, 해시 값 사용날짜시간::형식::기간모듈, 정규식 대체를 사용하여 나노초를 정규화합니다.

perl -MDateTime::Format::Duration -ane '
  BEGIN {
    $p = DateTime::Format::Duration->new(pattern => "%e-%H:%M:%S.%N");
  }

  $F[1] =~ s/\d+(\.\d+)?$/sprintf "%02.9f", $&/e;  
  $h{$F[0]} = $h{$F[0]} ? $dt->add_duration($h{$F[0]}) : $dt if $dt = $p->parse_duration($F[1]);

  END { 
    $p = DateTime::Format::Duration->new(pattern => "%e-%H:%M:%S.%3N", normalize => 1);
    for $k (sort keys %h) {printf "%s %s\n", $k, $p->format_duration($h{$k})}
  }
' file
aaa 1-21:27:26.255
bbb 5-11:15:04.433

답변3

perl -F'\h+|[-.:]' -lane '
   $h[keys %h]=$F[0] unless $h{$F[0]};
   $h{$F[0]}[$_-1] += $F[$_] for 1..$#F}{for ( @h )
   {
      my @Arefs = map { \$_ } my($days, $hrs, $mins, $secs, $msec) = @{$h{$_}};
      while ( $msec >= 1000 ) { $secs++; $msec -= 1000; }
      while ( $secs >=   60 ) { $mins++; $secs -=   60; }
      while ( $mins >=   60 ) { $hrs++;  $mins -=   60; }
      while ( $hrs  >=   24 ) { $days++; $hrs  -=   24; }
      print $_, sprintf " %d-%02d:%02d:%02d.%03d", map $$_, @Arefs;
   }
' text.file

perl -F'\h+|[-.:]' -lane '
   $h[keys %h]=$F[0] unless $h{$F[0]};
   $h{$F[0]}[$_-1] += $F[$_] for 1..$#F}{for ( @h )
   {
      use integer;
      my @A = @{$h{$_}};
      $A[0] += ($A[1] += ($A[2] += ($A[3] += $A[4]/1000)/60)/60)/24;
      $A[4] %= 1000; $A[3] %= 60;$A[2] %= 60; $A[1] %= 24;
      print $_, sprintf " %d-%02d:%02d:%02d.%03d", @A;
   }
' text_file

결과

aaa 1-21:27:26.255
bbb 5-11:15:04.433

설명하다

  • 필드 구분 기호는 밀리초, 초, 분, 시간, 일 및 첫 번째 필드 키를 구분하도록 설정됩니다.
  • @F입력 행은 분할 되어 다음 요소가 포함된 배열에 저장됩니다 : $F[0] -> 키(aaa/bbb/etc.) $F[1] -> 일, $F[2] -> 시간, $ F[3] -> 분, $F[4] -> 초, $F[5] -> 밀리초.
  • 해시 키는 본질적으로 생성된 순서대로 액세스되지 않으므로 @h표시되는 순서대로 해시 키를 요소로 하는 배열이 있습니다.%h
  • 해시는 %h다음과 같이 구성됩니다.

%h = (
    aaa => [ days, hours, minutes, seconds, milliseconds ],
    bbb => [                    ...                      ],
    ... 
 );

관련 정보