次のように、「;」で区切られた4つの列を持つファイルがあります。
Articles;Qty;Sales;Customers
ArticleA;2;6;Customer1
ArticleA;3;9;Customer2
ArticleA;5;15;Customer1
ArticleA;4;12;Customer1
ArticleB;1;2;Customer2
ArticleB;2;4;Customer1
ArticleC;3;3;Customer2
各記事の列2と列3を合計したいです。以下を使用してこれを実行できます。
awk -F ';' 'NR>1 {a[$1]+=$2; b[$1]+=$3} END {for (i in a) print i, a[i], b[i]}' File
しかし、今はこの記事を購入した顧客が何人であるかも知りたいです。残念ながら私はできません。誰かが私のawkコマンドが次の結果を得るためにどのように機能するべきかを教えてもらえますか?
Articles;Qty;Sales;Count of different customers
ArticleA;14;42;2
ArticleB;3;6;2
ArticleC;3;3;1
答え1
awk
実際の多次元配列のGNUと配列の関数があると仮定すると、length()
次のことができます。
gawk -F';' -v OFS=';' 'FNR==1{print "Articles;Qty;Sales;Count of different customers";next}
{qty[$1]+=$2;sls[$1]+=$3;cust[$1][$4]}
END{for (a in qty) {print a,qty[a],sls[a],length(cust[a])}}' input.ssv
入力ファイルの結果は次のとおりです。
Articles;Qty;Sales;Count of different customers
ArticleA;14;42;2
ArticleB;3;6;2
ArticleC;3;3;1
この計画は
- 最初の行をそのまま印刷し、実行のために次の行にジャンプします。
- 記事を「配列索引」として
qty
使用して、連想配列に数量と販売数値を追加します。sls
- 最初のインデックスが記事で、2番目のインデックスが顧客名である2次元配列に各顧客を登録します。
最後に、プログラムはすべての記事(配列のインデックスから取得qty
)を繰り返し、記事、総数量、総販売量、およびその記事の顧客配列の「長さ」を印刷します。これは顧客数と同じです。 。
答え2
そしてawk
:
awk 'BEGIN{ FS=OFS=";" }
NR>1{ s1[$1]+=$2; s2[$1]+=$3; c[$1, $4]=$1 }
END{
print "Articles", "Qty", "Sales", "Count of different customers"
for(x in c) cs[c[x]]++; for(i in cs) print i, s1[i], s2[i], cs[i]
}' infile