awkガナス

第1回 特定のフィールドの値を合計する

2015.05.13

今は perl,ruby,python など強力なスクリプト言語があるので、awk を使う人もすくないのではないかと思います。しかし、awk は記述が簡単で覚えやすく、複雑なこともできる強力なスクリプト言語です。

この記事では筆者が普段よく使う awk の事例などを書いていきたいと思います。

動作確認環境は Ubuntu14.04+ mawk1.3.3-17ubuntu2 です。

なお「awkガナス」は「awkの話」といったような意味です。

5番目のフィールドの値を合計する(a+=$5)

awkでは行中の空白を区切りとして分割したものをフィールドといい、$1,$2 のように表現します。awkは $1,$2 を使ってフィールド処理を簡単に記述できます。

たとえば ls -l コマンドの出力からバイト数の合計を計算する場合、バイト数は5番目のフィールドにあるので$5を変数aに加算していきます。

変数の初期化は自動で行われますので初期化の必要はありません。

文末のセミコロンは必要ありません。書いてもエラーにならないので書いてもよいです。

{a += $5}

このままだと何も出力されないので print a を記述し、合計値を出力します。

一行に複数の処理を書く場合は 処理の区切りとしてセミコロンを書きます。

{a += $5;print a}

コマンドラインで記述すると以下のようになります。

% ls -l /bin/| awk '{a += $5;print a}'
0
986672
1016912
2730336
..

数字だけだと何を表示しているのかよくわからないので行($0)も表示します。

% ls -l /bin/| awk '{a += $5;print a,$0}'
0 合計 9496
986672 -rwxr-xr-x 1 root root  986672  9月 27  2014 bash
1016912 -rwxr-xr-x 3 root root   30240 10月 21  2013 bunzip2
2730336 -rwxr-xr-x 1 root root 1713424 11月 15  2013 busybox
2760576 -rwxr-xr-x 3 root root   30240 10月 21  2013 bzcat
2760582 lrwxrwxrwx 1 root root       6 10月 21  2013 bzcmp -> bzdiff
..
左側の数値が合計バイト数。残りは読み込んだ文字列。

シンボリックリンクとかディレクトリの値も加算されるのでファイルだけを加算するようにします。

ファイルは先頭文字列が’-‘になるので {a += $5;print a,$0} の前に /^-/ を付けます。

% ls -l /bin/| awk '/^-/{a += $5;print a,$0}'
986672 -rwxr-xr-x 1 root root  986672  9月 27  2014 bash
1016912 -rwxr-xr-x 3 root root   30240 10月 21  2013 bunzip2
2730336 -rwxr-xr-x 1 root root 1713424 11月 15  2013 busybox
2760576 -rwxr-xr-x 3 root root   30240 10月 21  2013 bzcat
2762716 -rwxr-xr-x 1 root root    2140 10月 21  2013 bzdiff
2767593 -rwxr-xr-x 1 root root    4877 10月 21  2013 bzexe
..
左側の数値が合計バイト数。残りは読み込んだ文字列。

先頭文字列が ‘-‘ の行を取り出すために grep と組み合わせるのもアリです。

% ls -l /bin/| grep ^- | awk '{a += $5;print a,$0}'

合計値がバイト数だと数値が大きくなるとわかりにくいので1000で割ってKバイト単位にします。

% ls -l /bin/| awk '/^-/{a += $5;print a/1000,$0}'
986.672 -rwxr-xr-x 1 root root  986672  9月 27  2014 bash
1016.91 -rwxr-xr-x 3 root root   30240 10月 21  2013 bunzip2
2730.34 -rwxr-xr-x 1 root root 1713424 11月 15  2013 busybox
2760.58 -rwxr-xr-x 3 root root   30240 10月 21  2013 bzcat
2762.72 -rwxr-xr-x 1 root root    2140 10月 21  2013 bzdiff
2767.59 -rwxr-xr-x 1 root root    4877 10月 21  2013 bzexe
..

桁がそろっていないので printf で整形します。printfの書式はC言語とほぼ同じです。

% ls -l /bin/| awk '/^-/{a += $5;printf "%7.2f %s\n", a/1000,$0}'
 986.67 -rwxr-xr-x 1 root root  986672  9月 27  2014 bash
1016.91 -rwxr-xr-x 3 root root   30240 10月 21  2013 bunzip2
2730.34 -rwxr-xr-x 1 root root 1713424 11月 15  2013 busybox
2760.58 -rwxr-xr-x 3 root root   30240 10月 21  2013 bzcat
2762.72 -rwxr-xr-x 1 root root    2140 10月 21  2013 bzdiff
2767.59 -rwxr-xr-x 1 root root    4877 10月 21  2013 bzexe
..

著者プロフィール

naka

すきなコマンドは awk と bc です。なにかを計算する時、awk か bc を使います。

記事一覧Index