awk

$ awk '条件 { 処理 }' ファイル名

awkコマンドで、ファイルの中身を、任意の条件で簡単に抽出できます。 とても強力なツールのようなので、沼にハマるとやばそうな気がします。 ここでは、条件を満たす列や行を選択したり、出力を整形したりする方法を紹介します。

注釈

コマンド名は「オーク」と読みます。 Alfred Aho、Peter Weinberger、Brian Kernighanの3人の開発者名に由来するそうです。 Kernighanは「プログラミング言語C」のK&RのKのひとです。

ファイルを表示したい(print

// 全行を表示
$ awk '{ print }' ファイル名

// 行番号を追加
$ awk '{ print NR, $0 }' ファイル名

// 2行目から表示
$ awk 'NR>1 { print }' ファイル名

print関数で文字列を表示できます。

注釈

ファイル名の代わりにパイプした標準出力を受け取り、 表示形式を加工する使い方が多いです。

特定のフィールドを表示したい($1 $2 ...

// 1列目を表示
$ awk '{ print $1 }' ファイル名

// 2列目を表示
$ awk '{ print $2}' ファイル名

// カラムの順番を入れ替える
$ awk '{ print $1 $3 $2}' ファイル名

// 全行を表示
$ awk '{ print $0 }' ファイル名

$Nでフールド(=列番号)を抽出して表示できます。

変数したい(awk -v

$ awk -v date=$(date +%Y-%m-%d) '{ print date "," $0}' ファイル名

-vオプションで変数名を定義できます。

CSV形式に変換したい

$ awk '{ print $1 "," $2 "," $3 }' ファイル名 > 変換後のファイル名.csv

// 空白は詰めてもOK
$ awk '{print $1","$2","$3}'

スペース区切り(もしくはタブ区切り)のファイルを、カンマ区切りに変換できます。 $1などのフィールド変数はそのままでOKですが、 ,を文字としてクォートする必要があるため注意が必要です。

ディスク容量をしりたい

1#!/usr/bin/env
2
3set -euo pipefail
4
5ISO8601=$(date +%Y-%m-%dT%H:%M:%S%z)
6df --output | awk -v date="${ISO8601}" '{ print $1 "," $2 "," $5 }' > disk_usage.csv
7
8exit 0

dfコマンドの出力をCSV形式に変換したときのサンプルです。