はじめに
- 前回書いた記事でAWKをほんの少しだけ使用したが、AWKとは何ですか?とごく少数の人に聞かれたので自分の知っている範囲で記載します
- GNU awkであることを前提としています
AWKとは
- AWKとはAWKスクリプトを処理するインタプリタで、プログラミング言語のひとつである
- スクリプトを使用せずターミナルでワンライナーとして直接実行することが多い
- 空白文字区切りやカンマ区切りのテキスト型のデータファイルの処理に特化している
- AWKのそれぞれの文字は作った人の頭文字でKはC言語で有名なブライアン・カーニハン博士のKである
AWKの基本的な使い方
AWKの基礎
- 空白文字で区切られたテキストデータを行ごとに処理する
- 区切り文字は空白以外にも指定可能
- 行のことをレコードと呼ぶ
- 区切り文字で区切られたデータをフィールドと呼ぶ
- レコード、フィールドともに数えるのは$1から始まる
- 実行方法
awk 'パターン {アクション}'
- パターンが省略された場合はすべてのレコードに対しアクションを実行
- アクションが省略された場合はパターンにマッチしたレコードを表示
ワンライナーで実行する例
# 2番目のフィールドがbだったらhitと表示
echo "a b c" | awk '$2 == "b" {print "hit"}'
# 2番目のフィールドがbだったらBに置き換え(破壊的代入)
echo "a b c" | awk '$2 == "b" {$2 = "B"; print $0}'
# カンマ区切りのデータで3番目のフィールドが200超の場合にレコードを表示
echo "10, 1, 300" | awk -F',' '$3 > 200 {print $0}'
# リストコマンドの結果からディレクトリを除外してサイズが5000バイト超のものを表示
ls -al | awk 'NR > 3 && substr($1, 1, 1) != "d" && $5 > 5000 {print $9}'
# gitコマンドでブランチ一覧を表示しカレントとなっているブランチ名を表示
git branch --no-color | awk '$1 == "*" {print $2}'
# 改行コードがLFのテキストファイルについてCRLFに変えて別ファイルに出力
awk '{printf "%s\r\n", $0}' input.txt > output.txt
# カンマ区切りのファイルの内容について2番目のフィールドが4桁以上のときレコード番号とレコードを表示
awk -F',' '{if(length($2) >= 4) print NR ":" $0}' sample-data.csv
AWKスクリプトを読み込ませる例
# awk-script.awk
BEGIN{
# 変数などの初期化が必要であればここで
}
NR==1{
# マッチした場合の処理を記述
}
/^[0-9]*,/{
# マッチした場合の処理を記述
}
END{
# 終了処理が必要であればここで
}
awk -f awk-script.awk
AWK以外のスクリプト言語でも同じようなことできるのでは?
できます。
rubyやpythonでも同じようなことをワンライナーで書くことは可能です。
しかし、使用する環境でたまたま便利なスクリプト言語が入っておらず、さらにインストールもできない場合などawkを知っていると便利な状況があるのでこんなものもあるよと覚えておいても損はないかなと思います。
またawkは多くの関数を使用することができ、スクリプトファイルを作成すると結構何でもできる感じになります。
ただ、そこまでしっかり処理を書くならばAWK以外の選択があるかなとも思うので無理に何でもかんでもAWKでやる必要はなく、コマンドっぽく使うくらいがちょうどよいかなと個人的には思っています。