awkで、特定の列を集計してパーセントを計算した列を追加したいということがあったので、備忘で残しておく。 以下のように、ファイルを2回読み込ませてやり、1回目に集計処理を、2回目に読み込む際にパーセント列の計算をすることで実現できる。
awk 'NR==FNR{a=a+$2;next}{p=$2/a*100;print $0,p"%"}' file file
blacknon@BS-PUB-DEVELOP:~$ cat test2.list
a 4799
b 29975
c 29188
d 31047
e 11659
f 7653
g 19850
h 16754
i 16512
j 15015
k 26007
blacknon@BS-PUB-DEVELOP:~$ # 2列目の内容を集計して3列目にパーセントを表示
blacknon@BS-PUB-DEVELOP:~$ awk 'NR==FNR{a=a+$2;next}{p=$2/a*100;print $0,p"%"}' test2.list test2.list
a 4799 2.30213%
b 29975 14.3793%
c 29188 14.0018%
d 31047 14.8936%
e 11659 5.59295%
f 7653 3.67123%
g 19850 9.52226%
h 16754 8.03707%
i 16512 7.92098%
j 15015 7.20286%
k 26007 12.4758%
blacknon@BS-PUB-DEVELOP:~$ # 見やすく整形する
blacknon@BS-PUB-DEVELOP:~$ awk 'NR==FNR{a=a+$2;next}{p=$2/a*100;print $0,p"%"}' test2.list test2.list | column -t
a 4799 2.30213%
b 29975 14.3793%
c 29188 14.0018%
d 31047 14.8936%
e 11659 5.59295%
f 7653 3.67123%
g 19850 9.52226%
h 16754 8.03707%
i 16512 7.92098%
j 15015 7.20286%
k 26007 12.4758%
で、上記方法だとファイルの読み込みがキモになっているのだが、パイプから受け付けた内容に対してパーセント列を追加するにはどうすればいいのだろうか。
標準入力は一度読み込むと消えてしまうので、()
で括ってやって変数に代入する方法を取ることで対応できる。
cat file |(s=$(cat)&&awk 'NR==FNR{a=a+$2;next}{p=$2/a*100;print $0,p"%"}' <(echo -e "$s") <(echo -e "$s"))
blacknon@BS-PUB-DEVELOP:~$ cat test2.list |(s=$(cat)&&awk 'NR==FNR{a=a+$2;next}{p=$2/a*100;print $0,p"%"}' <(echo -e "$s") <(echo -e "$s"))
a 4799 2.30213%
b 29975 14.3793%
c 29188 14.0018%
d 31047 14.8936%
e 11659 5.59295%
f 7653 3.67123%
g 19850 9.52226%
h 16754 8.03707%
i 16512 7.92098%
j 15015 7.20286%
k 26007 12.4758%
blacknon@BS-PUB-DEVELOP:~$ cat test2.list |(s=$(cat)&&awk 'NR==FNR{a=a+$2;next}{p=$2/a*100;print $0,p"%"}' <(echo -e "$s") <(echo -e "$s")) | column -t
a 4799 2.30213%
b 29975 14.3793%
c 29188 14.0018%
d 31047 14.8936%
e 11659 5.59295%
f 7653 3.67123%
g 19850 9.52226%
h 16754 8.03707%
i 16512 7.92098%
j 15015 7.20286%
k 26007 12.4758%
blacknon@BS-PUB-DEVELOP:~$ # ついでに最終行に集計行を出力
blacknon@BS-PUB-DEVELOP:~$ cat test2.list |(s=$(cat)&&awk 'NR==FNR{a=a+$2;next}{p=$2/a*100;print $0,p"%"}END{print "TOTAL",a,"100%"}' <(echo -e "$s") <(echo -e "$s")) | column -t
a 4799 2.30213%
b 29975 14.3793%
c 29188 14.0018%
d 31047 14.8936%
e 11659 5.59295%
f 7653 3.67123%
g 19850 9.52226%
h 16754 8.03707%
i 16512 7.92098%
j 15015 7.20286%
k 26007 12.4758%
TOTAL 208459 100%