結果

結果

次のファイルがあります。

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)とイベントが発生した日付を示します。 1日に各タイプのイベント数を計算したいです。これはで行うことができ、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)を事前に知っていると仮定できますが、そうでない場合はそれがより良いです。繰り返しますが、各イベントが1日に1回以上発生すると仮定できますが(出力にゼロがないことを意味します)、これが必要でない場合はここで問題ありません。

答え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

(残念ながら、Webサイトの形式はタブを保持しません。実際の出力はタブの整列です。)

答え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        

関連情報