配列の使用awk

配列の使用awk

次の列を含むCSVがあります。

Team    Other Data  More Data   Result  Time
Knicks      A          F         Loss    2p
Celtics     B          E         Win     2p
Lakers      C          D         Loss    3p
Lakers      D          C         Loss    4p
Knicks      E          B         Win     4p
Lakers      F          A         Win     5p

CSVを読み、各チームの勝敗を出力するには?

たとえば、私が望む出力は次のようになります。

1 Loss Knicks
1 Win Knicks
1 Win Celtics
2 Loss Lakers
1 Win Lakers

今、次のコードがあります。

#!/bin/bash
while IFS=, read -r team result
do
  echo $team, $result
done < teams.csv

次の出力が生成されます。

Team, Result   
Knicks, Loss
Celtics, Win
Lakers, Loss
Lakers, Loss
Knicks, Win

各チームの各結果の発生回数をどのように計算して保存できますか?理想的には、このデータをチームごとにソートしたいと思います。

答え1

配列の使用awk

入力ファイルのフィールドが1つ以上のスペース文字で区切られている場合は、フィールド区切り文字を宣言する必要はありません。

awk 'NR>1 && NF { league[$1][$4]++ } END { for ( team in league ) for ( results in league[team] ) print league[team][results],results,team }' teams.txt

画面に合わせてフォーマットされた同じコード:

awk 'NR>1 && NF { league[$1][$4]++ }
     END { for ( team in league )
           for ( results in league[team] )
           print league[team][results],results,team }' teams.txt

ここでは、リーグ(入力ファイル)の各チーム(、最初のゲーム)の勝敗(、4番目のゲーム)の数を数えますleague[$1][$4]++$4$1

NR>1awkヘッダー(最初の行)が無視されることを意味します。

同様にNF、(の略語)は、1つ以上のフィールドを含む行のみをチェックすることをNF>0意味します。awkつまり、NF空行をスキップします。

このNR>1 && NFセクションでは、入力ファイルを調べて配列を作成します。完了すると、このENDセクションでは配列を印刷します。

入力ファイルのフィールドがコンマで区切られている場合は、BEGIN { FS="," ; OFS=" " }設定入力(FS)および出力(OFS)フィールド区切り文字を追加します。

awk 'BEGIN { FS="," ; OFS=" " } NR>1 && NF { league[$1][$4]++ } END { for ( team in league ) for ( results in league[team] ) print league[team][results],results,team }' teams.csv

画面に合わせてフォーマットされた同じコード:

awk 'BEGIN { FS="," ; OFS=" " }
         NR>1 && NF { league[$1][$4]++ }
         END { for ( team in league )
               for ( results in league[team] )
               print league[team][results],results,team }' teams.csv

出力:

1 Win Knicks
1 Loss Knicks
1 Win Lakers
2 Loss Lakers
1 Win Celtics

| sort -t " " -k 3 -k 2,2そのコードの最後に追加してチームごとに並べ替え、各チームの結果で並べ替えます。

ソートされた出力:

1 Win Celtics
1 Loss Knicks
1 Win Knicks
2 Loss Lakers
1 Win Lakers

答え2

あなたがしなければならないのは、ファイルを並べ替えてそれを渡すことによってuniq -c一意の発生回数を数えることです。

sort teams.csv | uniq -c

これにより、次のような出力が生成されます。

      1 Celtics,Win
      1 Knicks,Loss
      1 Knicks,Win
      2 Lakers,Loss

答え3

GNU datamashを使用してください(必要に応じてawkを使用して列を並べ替えます):

$ datamash -W --header-in groupby 1,4 count 4 < teams.csv | awk '{print $3, $2, $1}'
1 Loss Knicks
1 Win Celtics
2 Loss Lakers
1 Win Knicks
1 Win Lakers

私たちがいるので参考にしてくださいいいえdatamashにソートを要求すると、すでに隣接している結果のみがグループ化されます。

あなたのデータが実際に斑点分離と交換 -W 渡す -t,

答え4

ただ使用しsortてパイプに接続することもできますが、uniq -cここではTeam, Result

これを防ぐには:

$ awk 'NR>1 {print $4,$1}' team.csv | sort -k2 | uniq -c

各部分を説明してください。

  • awk 'NR>1 {print $4,$1}'- 最初の行より大きいすべての行と結果を印刷し、その後に列4と1で指定されたチームと結果を印刷します。
  • sort -k2- チーム別に並べ替えると、awk作業後2列目になります。
  • uniq -c- 固有の発生回数の計算

チームでソートされた出力:

1 Win Celtics
1 Loss Knicks
1 Win Knicks
2 Loss Lakers
1 Win Lakers

関連情報