fmemo

AWK

最終更新:

fmemo

- view
管理者のみ編集可

基本的な構文


$ awk 'pattern{action}' inputfile (> outputfile)
$ awk -f scriptfile inputfile (> outputfile)
  • ワンライナはシングルクォートの中に書く。
  • 出力ファイルを指定しないと計算結果は標準出力に書き出される。
  • スクリプトファイルを使うときは-fオプションをつける。

カラム数が1以上の行(つまり空行でない行)を出力する。
$ awk 'NF>0{print $0}' inputfile 

変数


  • 変数の宣言は必要ない。
  • 文字か数値かは文脈で決まる。
  • 強制的に文字列として認識させたいときは変数の後ろに""をつける。
  • 強制的に数値として認識させたいときは変数の後ろに+0をつける。

$ awk 'END{print var+0}' inputfile  #varは数値
$ awk 'END{print var""}' inputfile  #varは文字列

組み込み変数


  • NR 現在処理中のレコード数(いま何行目か)
  • NF 処理中のレコードのフィールド数(何カラムあるか)

file.txtの行頭に行番号をつけて表示する
awk '{print NR, $0}' file.txt

file.txtの各行のカラム数の合計を表示する
awk '{sum+=NF}END{print sum}' file.txt

区切り文字の変更


awkのデフォルトの区切り文字はスペース。変更したいときは-Fオプションをつかう。区切り文字を,(カンマ)にしたいとき。

$ awk -F, '{print $0}' inputfile

BEGIN文、END文


データを読み込む前に何か処理をしたいときはBEGIN文を、すべてのデータを読み込んだ後に何か処理をしたいときはEND文を使う。下の例はすべてのデータの第1カラムの和を表示する。

$ awk '{sum += $1}END{print sum}' inputfile

制御構文

if文


最も単純なもの。ifで当てはまったときのみ処理をする。

if (条件) ....

ifで当てはまらない場合の処理も入れる場合。

if (条件) .... else .... 

ifを複数使う場合。

if (条件) .... else if (条件) ... else if (条件) ... 

for文


C言語タイプのfor文

for ( ... ; ... ; ... ) ....

配列を使う場合

for (変数 in  配列) .... 

while文


条件が真である間、繰り返す。

while (条件) ...

次の例は、inputfileの第1列から第10列までを一行づつ表示する。

$ awk '{i=1; while(i<=10){print $i; ++i}}' inputfile

配列


awkの配列はhash(連想配列)になっている。
(書きかけ)

算術関数


atan2(y,x)
y/xのアークタンジェント。値域は-πからπ
cos(x)
コサイン(ラジアン)
exp(x)
指数関数
int(x)
整数にまるめる
log(x)
対数関数
rand()
0から1の間の乱数
sin(x)
サイン(ラジアン)
sqrt(x)
平方根
srand(x)
乱数の種。引数を指定しないときは時刻が使用される。

awkの中でシェル変数を使う


シングルクォートのペアはawkの手続きと解釈される。シェル変数部分をシングルクォートの外に出す。
file.txtの1列目がappleの行だけを表示したいとき。

#!/bin/sh
VAR=apple
awk '$1~/'$VAR'/{print $0}' file.txt

正規表現


  • ^文字列のはじめ
  • $文字列の最後

シングルクォートを出力したいとき


\047を使えば良い

$ echo abc | awk '{print "\047"$1"\047"}'
'abc'


文字列の切り抜き


substr(s,p)
sのp番目から後ろの部分文字列を返す
substr(s,p,n)
sのp番目から始まる長さnの部分文字列を返す

awk一行野郎(ワンライナ)集

便利な一行野郎たちをあつめる。

10行目以降を表示する。(ヘッダをとばすようなとき)
$ awk 'NR>10' input.txt

各行の先頭に行数を表示する
$ awk '{print NR, $0}' input.txt

ヒストグラムをつくる(divは分割する数)
$ awk 'BEGIN{num=0;div=500}{num++;i=int($2*div)+1; var[i]++}END{for(i in var){print (i-0.5)/div,var[i]/num*div}}' ifile | sort -n > ofile


時間関数


systime


unix秒(1970年1月1日からの通算秒)を表示する。
$ awk 'BEGIN{print systime()}' /dev/null 
1271732201

mktime


YYYYMMDDhhmmss形式の数字列からunix秒を計算する。
$ awk 'BEGIN{print mktime("2010 01 01 01 01 01")}' /dev/null
1262275261

strftime

指定したフォーマットで時刻を表示する。
$ awk 'BEGIN{print strftime()}' /dev/null
水 12 01 23:29:25 JST 2010

フォーマットの指定方法は
$ man strftime
で確認できる。

参考サイト




記事メニュー
人気記事ランキング
ウィキ募集バナー