awk

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 (条件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 (変数の初期化; 変数の条件式; 変数の変化){
    	処理
    }
    • 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行にしたい(ワンライナー)場合、「;」が改行の代わりになる
  • 対象データ: 第1フィールドにステップ数、第2フィールドに値があるデータ
  • コード (バッチファイル)
    sumaverage.awk
    #!/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}'
  • awk.txt
  • 最終更新: 2018/03/13 16:46
  • by mumeiyamibito