awk を使ってターミナル上で必要な部分の列和を計算する

SNP とかなんでもいいのだが、行列データがあって、ある列のデータのうち条件をみたすものだけを抽出して、和を取りたい。
それをR とかPython を使わずに、シェルというかawk で完結したいのだが、という悩みを同僚が言ってきたのでやってみた。
 
一発でsum みたいな関数で和が出るわけではないので、必要な列を取る > 条件分岐する > increment で足す > 最後にprint する、という感じでやればこんな感じ。
awk で変数を引数にとるには -v オプションを使えばいいので、シェル芸人できる。
サンプルデータの作成にはR でワンライナーを使った。

R -q -e 'write.table(matrix(ceiling(runif(10*20, 1, 1000)), 20), "testmat.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)'
cat testmat.txt
awk '{if($2 > 800) total = total + $2};END{print total}' testmat.txt

サンプルデータはこんな感じで

283 362 409 13 703 991 907 765 932 947
790 141 739 100 356 795 169 650 635 747
267 531 53 891 587 273 821 164 124 548
465 332 425 431 377 761 125 316 901 495
636 139 424 736 777 152 793 143 282 908
367 335 568 468 377 478 79 38 471 395
12 773 929 556 418 503 539 305 210 348
265 584 193 211 184 72 346 967 343 212
981 727 444 324 300 511 773 549 453 607
37 87 892 808 538 413 837 746 471 51
798 488 798 810 952 682 74 38 826 21
576 985 498 788 571 671 683 930 39 335
278 413 154 409 413 155 807 523 513 545
104 30 257 455 979 232 415 935 174 258
962 993 59 291 8 809 243 793 430 47
782 17 465 925 483 109 740 250 782 804
578 51 265 666 40 991 211 476 964 353
110 730 443 805 580 373 498 276 832 524
438 188 327 638 260 664 478 810 256 59
888 387 781 425 747 905 783 472 824 274

全然イケてないけどR のワンライナーで検算すれば

R -q -e 'sum(read.table("testmat.txt")[read.table("testmat.txt")[,2]>800,2])'

Python で書けば

python -c "import numpy as np; a=np.loadtxt('testmat.txt'); print(np.sum(a[np.where(a[:,1]>800),1])) "