列内の負の値の発生回数を計算し、関連する行名をリストするAwkスクリプト

列内の負の値の発生回数を計算し、関連する行名をリストするAwkスクリプト

列に負の値を持つ国のリストを生成して計算するawkスクリプトを作成しようとしています。

サンプル:

Country, COL2,COL3,COL4,COL5
Poland,  -0.3, 0,   2,  -0.5
Canada,  -1,   1,   1,  -0.4
Italy,    7,  -5,   3,  -0.1
France,   1,   2,  -0.5, 7 
Portugal, 1,   NULL,   4,   1

希望の出力:

2 COL2, Poland, Canada, 
1 COL3, Italy, 
1 COL4, France, 
3 COL5, Poland, Canada, Italy, 

スクリプトの作成を開始しましたが、期待した結果に近いものではありません。

#!/usr/bin/bash 

INPUT=./happiness2.csv
OLDIFS=$IFS
IFS=','

awk 'NF==1{next} 
  {country=$1; $1=""; gsub(/[^-]/,"",$0); l=length($0); 
   print country, l;
        }
  }' < $INPUT

誰でも助けることができますか?

ベストアンサー1

ハードコーディングではなく、最初の行から列名を読みます。最初の行の余分なスペースを削除できる場合は、出力をよりきれいにするのに役立ちます。

編集する:

#!/usr/bin/awk -f
# The arrays are
# name, indexed by column number, the names of the columns taken from the first line.
# cl, indexed by the column name, the list of countries for which
#    this column is negative.
# cnt, indexed by column name, the count of the number of countries.
BEGIN { FS="," }
NR==1 { for(i=2;i<=NF;i++) { name[i]=$i } ; next }
{
    # loop over the columns
    for(i=2;i<=NF;i++) {
        # get the value of the column as a number
        v=$i+0
        # move on to the next column if the value is non negative.
        if (v>=0) continue;
        # get the name of the column
        n=name[i]
        # increment the count and add the country onto the list
        cnt[n]++
        cl[n] = cl[n]  $1  ", "
    }
}
END { # At the end, loop over the results.
      for (i in name) {
        # get the column name
        n=name[i]
        # print out the saved data
        printf("%d %s, %s\n",cnt[n]+0, n, cl[n]); }}

出力順序は明確に定義されていません。

一般に、誰かが説明を求めると、それを提供するのが役立ちます。

おすすめ記事