결과

결과

다음과 같은 파일이 있습니다.

2017-07-30 A
2017-07-30 B
2017-07-30 B
2017-07-30 A
2017-07-30 A
2017-07-30 C
2017-07-31 A
2017-07-31 B
2017-07-31 C
2017-07-31 B
2017-07-31 C

각 줄은 사건(A, B, C)과 사건이 발생한 날짜를 나타냅니다. 하루에 각 유형의 이벤트 수를 계산하고 싶습니다. 이는 를 통해 수행할 수 있으며 sort file | uniq -c출력은 다음과 같습니다.

  3     2017-07-30 A
  2     2017-07-30 B
  1     2017-07-30 C
  1     2017-07-31 A
  2     2017-07-31 B
  2     2017-07-31 C

그러나 각 이벤트 유형을 열로 사용하고 싶습니다.

              A    B    C
2017-07-30    3    2    1
2017-07-31    1    2    2

이 작업을 수행할 수 있는 매우 일반적인 명령줄 도구가 있습니까?필요한 경우 모든 이벤트 유형(A, B, C)을 미리 알고 있다고 가정할 수 있지만, 그렇지 않은 경우에는 그게 더 좋습니다. 다시 말하지만, 각 이벤트가 하루에 한 번 이상 발생한다고 가정할 수 있지만(출력에 0이 없음을 의미), 이것이 필요하지 않다면 여기서는 괜찮습니다.

답변1

"상당히 일반적"에 다음이 포함되는 경우GNU 데이터 혼합, 그 다음에

datamash -Ws crosstab 1,2 < file

전임자.

$ datamash -Ws crosstab 1,2 < file
    A   B   C
2017-07-30  3   2   1
2017-07-31  1   2   2

(불행히도 웹사이트 형식은 탭을 유지하지 않습니다. 실제 출력은 탭 정렬입니다.)

답변2

해결책:

awk '{ d[$1]; k[$2]; a[$2,$1]++ }END{ 
       printf("%10s"," ");
       for(i in k) printf("\t%s",i); print ""; 
       for(j in d) { 
           printf("%-10s",j); 
           for(i in k) printf("\t%d",a[i,j]); print "" 
       } }' file

산출:

            A   B   C
2017-07-30  3   2   1
2017-07-31  1   2   2

답변3

더 짧은 버전에서는 null 값을 0에 할당하지 않습니다.

perl -lane '
   ++$h{$i[!$h{$F[0]} ? @i : -1]=$F[0]}{$F[1]}}{
   print join "\t", "\t", @h = sort keys %{ +{ map { map { $_ => 1 } keys %$_ } values %h } };
   print join "\t", $_, @{$h{$_}}{@h} for @i;
' yourfile

perl -lane '
   $i[@i]=$F[0] unless $h{$F[0]};
   ++$h{$F[0]}{$F[1]}}{
   @h = sort keys %{ +{ map { map { $_ => 1 } keys %$_ } values %h } };
   print join "\t", "\t", @h;
   for my $date ( @i ) {
      my $href = $h{$date};
      print join "\t", $date, map { $href->{$_} || 0 } @h;
   }
' yourfile

결과

                A       B       C
2017-07-30      3       2       1
2017-07-31      1       2       2

데이터 구조:

  • %h키가 A, B, C 등인 날짜와 값을 포함하는 해시 하위 해시 keys이며 해당 값은 해당 특정 날짜에 대한 각각의 개수입니다.

  %h = (
       2017-07-30 => {
           A => 3,
           B => 2,
           C => 1,
       },
       ...
  );

  • @i날짜가 발생한 순서대로 저장하는 배열입니다. @i이전에 본 적이 없거나 처음으로 본 경우에만 날짜를 배열에 푸시합니다. 순서는 배열 위치에 따라 제공됩니다.
  • @h해시의 모든 "A", "B", "C" 등의 키를 합산한 후 배열은 고유한 키를 갖게 됩니다 %h.

답변4

용법: ./count.awk input.txt | column -t -n

#!/usr/bin/gawk -f

{
    dates[$1] = $1;
    events[$2] = $2;
    numbers[$1][$2]++;
}

END {
    num_dates=asort(dates);
    num_events=asort(events);

    for (i = 1; i <= num_events; i++) {
        printf " %s", events[i];
    }
    print "";

    for (i = 1; i <= num_dates; i++ ) {
        printf "%s ", dates[i];
        for (j = 1; j <= num_events; j++) {
            printf "%s ", numbers[dates[i]][events[j]];
        }
        print "";
    }
}

시험:

입력하다(테스트가 복잡함)

2017-07-30 A
2017-07-30 D
2017-07-29 D
2017-07-30 B
2017-07-28 E
2017-07-30 B
2017-07-30 A
2017-07-30 A
2017-07-30 C
2017-07-31 A
2017-07-31 B
2017-07-31 C
2017-07-31 B 
2017-07-31 C

산출

            A  B  C  D  E
2017-07-28              1  
2017-07-29           1     
2017-07-30  3  2  1  1     
2017-07-31  1  2  2        

관련 정보