ワンライナーで awk 内で for 文を回したくなることが多々あるのですが、いつも方法を忘れるのでこれを機にまとめておきたいと思います。
基本的な使い方
基本は、
for( i=<start>; i<=<end>; <increment> ){ action }
の形をしており、他の言語と似ていると思われます。
以下では 1 から 5 までループを回し、そのインデックスを出力させています。
$ awk 'BEGIN{for(i=1; i<=5; i++){print i}}' 1 2 3 4 5
余談ですが、上記のように入力を何も取らず awk のみで機能を試したい時は、
各行の和を求める
次に、少し実践的な内容として、「数字が横に並んでいてその和を求める」といったことをやってみます。
イメージとしては
1 2 3
という入力に対し、
1+2+3 = 6
と答えるようなものを考えます。
$ echo '1 2 3 4 5 6 7 8 9 10' 1 2 3 4 5 6 7 8 9 10 $ echo '1 2 3 4 5 6 7 8 9 10' | \ awk '{for(i=1; i<=NF; i++){ sum+=$i }}END{ print sum }' 55
フィールド(列)の数だけループを回し、sum という変数に値を追加しています。awk の変数は明示されなければ、0で初期化されるという特徴があります。
各フィールドには $i という方法でアクセスできます。
また、awk 内部の特殊な変数として、行におけるフィールドの総数 NF
が用意されており、ループを回す条件として利用することが多いです。
ただ、上の例であれば awk を使わずに以下のように bc を用いる方が楽だと思います。
$ echo '1 2 3 4 5 6 7 8 9 10' |\ tr ' ' '+' | bc 55 # bc の基本的な使い方 $ echo '4*3' | bc 12 # それに合わせて tr を使って変形してあげる $ echo '1 2 3 4 5 6 7 8 9 10' |\ tr ' ' '+' 1+2+3+4+5+6+7+8+9+10
(おまけ)九九表を作る
$ awk 'BEGIN{for(i=1; i<=9; i++){for(j=1; j<=9; j++){printf"%2s\n",i*j}}}' \ | paste -d ' ' - - - - - - - - - 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81
おわりに
他の言語と同じように for 文を使いこなせるようになると、ワンライナーでできる幅が広がると思います。是非自分の思い通りにループを回せるようになりましょう。