テキストを整形する

INPUT · スライド

列を計算する(`awk`)

01 / 07

これまでできなかった2つのこと

この章で困ったことを思い出してみて。

1. cut は空白の幅がそろっていないと崩れる
2. 合計や平均が出せない

点数の列を抜くことはできても、足し算はできなかったよね。sortuniq も、数を並べたり数えたりはできるけれど、計算はできないんだ。

awk はその両方を解決するよ。列を扱うことに特化した、小さなプログラミング言語なんだ。

02 / 07

`$1` `$2` が列を表す

awk のいちばん基本の形はこれだよ。

```
awk '{print $2}' sukima.txt
```

$1 が1列目、$2 が2列目……という意味だね。$0行全体だよ。

{} の中に「各行で何をするか」を書くんだ。awk はファイルを1行ずつ読んで、行ごとに {} の中を実行するよ。

そして空白の幅を気にしないtanaka 80 でも suzuki 95 でも、$2 はちゃんと点数になるんだ。ここが cut との大きな違いだよ。

~ $ awk '{print $2}' sukima.txt809572

03 / 07

区切りを変えるのは `-F`

CSV のようにカンマ区切りなら -F で指定するよ(field separator の F だね)。

```
awk -F, '{print $1}' seiseki.csv
```

cut -d に当たるものだね。名前が違うだけで役目は同じだよ。

列を入れかえられるのも cut との違いだよ。

```
awk -F, '{print $2, $1}' seiseki.csv # 80 tanaka
awk -F, '{print $3 "," $1}' seiseki.csv # 3,tanaka
```

print にカンマで並べると空白でつながり、"," を挟むとカンマでつながるよ。cut -f2,1 が効かなかったのを覚えているかな。awk なら自由だよ。

04 / 07

`NR` と `NF` — 番号と列数

awk は便利な値を用意してくれているよ。

| 名前 | 意味 |
| --- | --- |
| NR | いま何行目か(Number of Records) |
| NF | この行に列がいくつあるか(Number of Fields) |
| $NF | 最後の列 |

```
awk '{print NR, $1}' sukima.txt # 行番号を振る
awk '{print $NF}' access.log # 最後の列だけ
```

$NF は覚えておくと便利だよ。列の数が行によって違うデータでも、最後の列は取り出せるからね。

NR を使えば nl の代わりにもなるね。同じことが何通りもの道具でできるのは、もう見慣れたね。

05 / 07

条件を書いて行を選ぶ

{} の前に条件を書くと、当てはまる行だけを処理するよ。

```
awk -F, '$2 > 80 {print $1}' seiseki.csv # 80点より上の人の名前
awk -F, '$1 == "sato" {print $2}' seiseki.csv
awk -F, '/tanaka/ {print $2}' seiseki.csv # tanaka を含む行
awk -F, 'NR == 2 {print $1}' seiseki.csv # 2行目
```

grep を超えているのに気づいたかな。grep は文字として探すことしかできなかったけれど、awk は「2列目が80より大きい」という数の比較ができるんだ。

{print} を省くと「行全体を出す」になるよ。だから awk -F, '$2 > 80' seiseki.csv だけで絞り込みができるんだ。

06 / 07

`END` で合計を出す

これが awk のいちばんの値打ちだよ。合計が出せるんだ。

```
awk -F, '{sum += $2} END {print sum}' seiseki.csv
```

読み方はこうだよ。

  • {sum += $2} … 各行で sum に2列目を足していく
  • END {print sum}全部の行を読み終わったあとsum を出す

END は「最後に1回だけやること」を書く場所だよ。逆に BEGIN は「始める前に1回だけ」だね(見出し行を付けるときに使うよ)。

平均も出せるよ。NR が行数になっているからね。

```
awk -F, '{sum += $2} END {print sum/NR}' seiseki.csv
```

sum を用意する宣言が要らないのに気づいたかな。awk では使い始めた変数は自動で 0 から始まるんだ。

07 / 07

さあ、打ってみよう

ファイルは3つだよ。

  • seiseki.csv名前,点数,順位 が3行
  • sukima.txttanaka 80 のように空白の幅がバラバラ
  • access.log住所 方法 パス 結果 が3行(本物のログを小さくしたもの)

シングルクォートで囲むのを忘れないでね。$ はシェルにとっても特別な文字なので、囲まないと $1 が消えてしまうんだ。

awk は奥が深くて、これだけで本が書ける道具だよ。この回で扱うのは列の取り出しと計算だけ。それでも日々の仕事のほとんどは足りるよ。