====== awk ======
===== 概要 =====
* プログラミング言語の1つ
* 特定の文字で区切られたデータが記述されたテキストを処理する際に便利
* 現在の Linux ディストリビューションで使える awk の実体は awk ではなく、gawk (awk は gawk のリンクになっている)
===== 処理の流れ =====
* 1行ずつ処理していく
* 以下の順にプログラムは進む
* 前処理: BEGIN{...}
* 省略可
* 本処理: {...}
* {...} の前にパターン (正規表現可) をつけると、パターンの行のみ処理する
* 後処理: END{...}
* 省略可
* awk にはファイル保存機能はないため、リダイレクトやパイプを使ってデータを保存したり、渡したりする
===== 実行方法 =====
* ワンライナー\\ $ awk [オプション] '処理内容' データ
* バッチファイル1 (awk に読み込ませる)\\ $ awk [オプション] -f バッチファイル データ
* バッチファイルとは awk の処理内容を記述したファイル
* バッチファイル2 (単体で動かす) \\ $ chmod +x バッチファイル
$ ./バッチファイル データ
* ただし、バッチファイルの先頭に ''#!/usr/bin/awk -f'' を付けること (/usr/bin/awk は環境によって異なるので、which コマンドなどで確認すること)
* パイプデータ処理\\ $ コマンド | awk [オプション]
==== オプション ====
^ 表記 ^ 効果 ^ 備考 ^
|-F __区切り文字__|区切り文字(入力フィールドセパレータ)の変更| |
|-v __変数名__=__変数値__|awk 内に変数を渡す|シェル内での実行の際、シェル変数を awk に渡したい時に使う|
|-f __バッチファイル__|バッチファイルに記述した処理をする||
===== 用語 =====
* レコード: 入力レコードセパレータで分割されたデータ
* フィールド: フィールドセパレータで分割されたデータ
===== 構文 =====
==== 全体のコード ====
#!/usr/bin/awk
BEGIN{
開始処理
}
/正規表現パターン1/{
パターン1に対する処理
}
/正規表現パターン2/{
パターン2に対する処理
}
:
END{
終了処理
}
==== 変数 ====
* 変数
* $0: レコード (行全体)
* $1, $2, $3, ...: フィールドの各データ
* 変数は自分で定義することも可能 (定義は不要)
* よく使う組み込み変数
* FS: 区切り文字 (データ間を区切る文字)
* オプション ''-F 区切り文字'' で変更可 (区切り文字は正規表現での表現可)
==== 配列 ====
* 複数のデータをひとまとめにした変数
* 定義は不要
* 配列のインデックスは 1 から始まる (0 ではない)
==== 演算子 ====
* 演算
* 四則演算が使える
* +, -, *, /
* インクリメンタル (++) やデクリメント (--) が使える
* 代入演算子 (+= や -= など) が使える
==== if ====
* 条件を分岐する場合\\
if (条件1){
処理1
else if (条件2){
処理2
}
else{
処理3
}
* 例:\\
if (i == 0){
print "0"
}
else if (0 < i && i < 10){
print "1-9"
}
else{
print "10 over"
}
* 条件式で使える記号
* <, >, <=, =>, == (数値、文字列の比較に使う), !=
* &&, ||
* 正規表現では ~ で正規表現とつなげる (例: i ~ /hoge/)
==== for ====
* 繰り返し処理をする場合に使う\\
for (変数の初期化; 変数の条件式; 変数の変化){
処理
}
* C 言語の for 文と一緒
* 例\\
for (i = 0; i < 3; i ++){
print "Hello"
}
Hello を 3 回出力
==== よく使う関数 ====
* print\\ print "文字列"
* 変数の中身などを出力
* 複数のデータを表示する場合は、スペースで区切って列挙 (例: print $1 "\t" $2 $3)
* スペースやタブを出力したい場合は、''" "'' や ''"\t"'' を変数の間に入れる
* printf\\ printf("フォーマット", 値)
* C 言語の printf と同じく、変数の内容を整形して表示
* %s: 文字列 (s の前に整数があると、スペースでその数だけの幅に整形する; 正の整数を入れると右揃え、負の整数を入れると左揃え)
* %d: 整数 (d の前に整数があると、スペースでその数だけの幅に整形する; 正の整数を入れると右揃え、負の整数を入れると左揃え)
* %f: 浮動小数 (f の前に小数があると、整数部を全体の幅、小数部を小数点以下の桁数にする; 整数部の前に 0 を付けると、ゼロで空白部を埋める)
* sub, gsub\\ sub(正規表現, 置換後の文字列, 対象とする文字列)
* 文字列の置換をする
* sub は 1 回のみ、gsub は繰り返し置換 (正規表現の s/str/replace/g) みたいなもの
* 例: str = 'banana' として、a を "" (削除) する場合
* sub\\ sub(/a/, "", str)
⇒ bnana
* gsub\\ gsub(/a/, "", str)
⇒ bnn
* split\\ split(対象文字列, 配列, 区切り文字)
* **対象文字列** を **区切り文字** で区切って、**配列** に代入する関数
* 返り値は、配列の要素数になる\\ hoge = split("banana", data, "a")
hoge は 3、data には「b」「n」「n」が入る
* length\\ length(配列)
* 文字列や配列の長さを出力
==== その他 ====
* 改行
* 複数行を1行にしたい(ワンライナー)場合、「;」が改行の代わりになる
===== awk プログラムの例 =====
==== 合計と平均算出 ====
* 対象データ: 第1フィールドにステップ数、第2フィールドに値があるデータ
* コード (バッチファイル)\\
#!/usr/bin/awk -f
BEGIN{
total = 0
count = 0
}
$0 !~ /^#/{
total += $2
count ++
}
END{
average = total / count
print "Total: " total
print "Average: " average
}
* 実行方法
* バッチファイル\\ $ awk -f sumaverage.awk data.txt
* バッチファイル単体\\
$ chmod +x sumaverage.awk
$ ./sumaverage.awk data.txt
* コード (ワンライナー)\\
$ awk 'BEGIN{total = 0; count = 0} $0!~/^#/{total += $2; count ++} END{average = total / count; print "Total: " total; print "Average: " average}'
===== Tips =====
==== シェル変数をパターンとして引き渡す ====
* ''-v'' オプションで変数を渡しつつ、''$0 ~ VAR'' でマッチさせる\\ $ awk -v VAR '$0 ~ VAR{print $0}' FILE
* ''VAR'' は変数名
* ''FILE'' は処理するファイル名
* 参考サイト: [[https://stackoverflow.com/questions/39384283/how-to-match-a-pattern-given-in-a-variable-in-awk | regex - How to match a pattern given in a variable in awk? - Stack Overflow]]
===== 参考サイト =====
* [[http://homepage2.nifty.com/mozu/koza/park_of_text.html | テキストの遊園地]]
* [[http://www.mothprog.com/prog/awk/awk8.html | Awkことはじめ]] バッチファイルについて
* [[http://www.techscore.com/blog/2012/11/19/%E3%81%82%E3%81%88%E3%81%A6%E8%A8%80%E3%81%86%E3%81%BB%E3%81%A9%E3%81%A7%E3%81%AF%E3%81%AA%E3%81%84%E3%81%91%E3%82%8C%E3%81%A9%E3%82%82%E3%80%81awk%E3%81%AE%E5%8C%BA%E5%88%87%E3%82%8A%E6%96%87/ | » あえて言うほどではないけれども、awkの区切り文字について TECHSCORE BLOG]] 区切り文字
* [[http://itdoc.hitachi.co.jp/manuals/3020/30203S3530/JPAS0241.HTM | awkコマンド(テキストの加工やパターン処理をする)]]
* [[http://shellscript.sunone.me/awk.html | AWK リファレンス | UNIX & Linux コマンド・シェルスクリプト リファレンス]]
{{tag>プログラミング コマンド}}