====== 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>プログラミング コマンド}}