行思考プログラミング

refs:dotinstall

■テストファイル
test_awk $ cat sales.dat
dotinstall item-5 100 2013/03/15 17:26:55
dotinstall item-2 250 2013/03/16 04:45:14
dotinstall item-2 250 2013/03/16 04:45:14
fkoji item-4 10 2013/03/07 16:40:24
fkoji item-4 10 2013/03/07 16:40:24
fkoji item-4 10 2013/03/07 16:40:24
hoge item-2 200 2013/03/09 07:38:57
fkoji item-4 10 2013/03/07 16:40:24
fkoji item-4 10 2013/03/07 16:40:24
fkoji item-4 10 2013/03/07 16:40:24
ta item-2 200 2013/03/09 07:38:57

■3列目を抜き出し表示、外だしのawkプログラムを実行
test_awk $ cat ex1.awk
{ print $3 }

test_awk $ awk -f ex1.awk sales.dat
100
250
250
10
10
10
200
10
10
10
200

■awk構文
test_awk $ cat ex1.awk
{
    # comment
    print $3
    print $4;
 }

文の区切りは改行か; コメントは#以降

■一行プログラム
test_awk $ awk '{print $2}' sales.dat
シングルクォーテで囲む

■特殊変数、レコード、フィールド
$2:2列目
$0:レコード全体
$NF:レコードの最後の項目
NR:行カウント
FS:フィールドセパレータの指定。デフォルトはスペース、タブ?

test_awk $ awk '{print $NF; print NR ":" $0}' sales.dat

■パターン
パターンを指定しない場合、すべてのレコードが対象。ある行だけを対象にしたい場合、パターンを使う。awk1はパターンと処理の組み合わせになる。
BEGINは処理の最初に一回だけ実行、ENDは処理の最後に一回だけ実行。

さんぷる
test_awk $ cat ex1.awk
BEGIN {
    print "----- start -----"
    FS = "-"
}
# 一つ目のハイフン"-"の前
{
    print NR ":" $1
}
# 5行目より前
NR < 5 {
    print NR ":" $0
}
# 7行目より前
NR  > 7 {
    print NR ":" $0
}

END {
    print "----- end -----"
}

その他のパターン
NR == 5, NR == 10 {print $0}
パターンをカンマで区切るとここからここまでという意味。上は5行目から10行目

# < > <= >= == !=
論理演算子
# && || !

# (NR == 5) || (NR > 10)

正規表現
# ~ !~

$2 ~ /item-[23]/  {
    print NR ":" $0
}
2つ目のフィールドがitem2かitem3

■フォーマット printf
test_awk $ cat ex2.awk
#printf
{
    # nameが20桁、salesが10桁
    printf("name : %20s sales : %10d\n", $1, $3)
}

{
    # -をつけて左寄せにする
    printf("name : %-20s sales : %-10d\n", $1, $3)
}

■変数、演算子
演算子は+=, ++インクリメント,--1がある。

さんぷる
全レコードの3列目の数値の合計を表示する
$ cat ex3.awk
# 変数 演算子
# += ++ --
# スペースで文字列連結
BEGIN {
    sum = 0
}
{
    sum = sum + $3
}
END {
    printf sum
}

■組み込み関数
rand():0~1の乱数発生
int():整数部分の抽出
length():長さ
substr():1部分文字列の取得

length($1) > 7:1列目の項目の長さが7より大きいとき
length($1) > 4:z1列目の項目の長さがzz74より大きいとき,刑務所ですっきりして:

■構文
if,while,for

■配列
test_awk $ cat ex_ary.awk
BEGIN {
    sales[1] = 200
    sales[2] = 120
    sales[3] = 50
    print sales[3]

    color = "yellow red blue"
    split(color, colors)
    print colors[3]

    for(i in colors){
        print colors[i]
    }
}

test_awk $ cat ex_ary2.awk
{
    sales[$1] += $3
}

END{
    for(name in sales){
        print name ":" sales[name]
    }
}

■関数

一行ずつ適応される

$ cat ex_func.awk
# function

function getRate(n){
    return int(n / 100) * 0.1
}

{
    printf("%-12s %5d rate:%0.1f\n", $1, $3, getRate($3))
}