C言語に似た文法を持つスクリプト言語。テキストファイルを加工するのに使う。
% awk "1行プログラム" hoge.txt
% awk -f プログラムファイル hoge.txt
入力ファイルを読み込み、データを1行ずつ、プログラムに従って編集・出力する。(標準出力に出力される)
入力ファイルを省略した場合は、標準入力からデータを読み込む。
-fオプションでファイル名に「-(ハイフン)」を指定すると、標準入力からプログラムが入力できる。[2007-04-24]
ただし「シェルの中にヒアドキュメントでプログラムを書く」という使い方をする場合は
$がシェルの変数と認識されてしまうので、\でエスケープする必要がある。
% cat sample.sh
#!/bin/sh
awk -f - hoge.txt <<EOF
{ print \$0 }
EOF
プログラムファイルに実行権限を付けて ファイルの先頭行に「#!
/bin/awk
-f
」(awkのコマンドのパスと-fオプション)を入れると、ファイルを直接実行することが出来る。[2007-05-12]
% cat exe.awk #!/bin/awk -f BEGIN { print "zzz" } { print FILENAME;exit } % chmod +x exe.awk % exe.awk input.txt zzz input.txt
プログラムは、おおよそ1行に『条件』と『その条件が満たされたときの処理』を記述していく。
条件・処理は、入力データの1行ずつに適用される。
複数行のプログラムを書いた場合は、入力データの1行ずつに対し、順番に条件がチェックされる。(途中でnext命令を実行すると、次のデータ行に移る)
入力データの行がA,B,Cとあり、プログラムの行がp1,p2だった場合、「Aに対してp1→p2」⇒「Bに対してp1→p2」⇒「Cに対してp1→p2」という順で処理される。
プログラム行の形式 | 動作 | 備考 |
---|---|---|
条件 { 処理 } | 条件が満たされた時に処理を行う。 | |
条件 | 条件が満たされた時に、入力データ行をそのまま出力する。 | { print }という処理が省略されている。 |
{ 処理 } | 常に処理を行う。 | 条件が省略されている。 |
#〜 | 行コメント |
条件には、C言語で使えるような比較演算が使用できる。&&や||も使える。
その条件が満たされたとき、直後に書かれているブロック(処理)が実行される。
条件を省略すると、常に処理が実行される。
基本的には、「“$0や$1といった変数”に格納されている文字列」と比較することがほとんど。
awkでは、文字列に対しても「==
」といった比較演算子がそのままの意味で使える。
/正規表現/ |
$0の中に正規表現にマッチする箇所があれば、真 | if文では使えない |
!/正規表現/ |
$0の中に正規表現にマッチする箇所が無ければ、真 | |
変数 ~ /正規表現/ |
変数の中に正規表現にマッチする箇所があれば、真 | if文でも使える |
変数 !~ /正規表現/ |
変数の中に正規表現にマッチする箇所が無ければ、真 |
開始条件,終了条件 |
開始条件に合致した行から、終了条件に合致する行まで、全ての行を出力する。 終了条件が出た後に再び開始条件に合致したら、再度出力対象になる。 |
→行番号での範囲指定 |
BEGIN |
ファイル処理の一番最初に一回だけ呼ばれる。変数の初期化に使える。 |
END |
ファイル処理の一番最後に一回だけ呼ばれる。 |
※複数のデータファイルが指定されている場合でも、BEGIN・ENDは 全体の最初と最後の一回ずつしか呼ばれない。[2007-05-14]
条件を複数行にわたって書きたい場合は、行末に「\」を付けることで 次の行に継続できる。[2007-05-14]
入力データの行がA,B,Cで、プログラムがBEGIN,p,ENDだった場合、「BEGIN」⇒「Aに対してp」⇒「Bに対してp」⇒「Cに対してp」⇒「END」という順で処理される。
BEGIN { count = 0; }
$1 == "hoge" { count++; }
END { print count; }
BEGIN { cnt1=0;cnt2=0; } /hoge1/ { cnt1++; } /hoge2/ { cnt2++; } END { print cnt1,cnt2; }
「{ 〜 }」ブロックでくくると、データを処理する動作(アクション・命令)の記述となる。
複数の命令を記述する場合は、セミコロン「;
」で区切る。(C言語と異なり、末尾のセミコロンは不要だが、付けても構わない)
ブロックの中は改行可能。
変数も使用できる。変数の定義(宣言)は特に必要なく、代入すればそのまま使える。
変数には型(数値・文字列)といった概念は無く、数値も文字列もどちらも入れられる。
計算に使えば数値として扱われるので、数値として代入したいときは「a = $2 * 1」のように演算を行ってやる。
命令 | 内容 |
---|---|
入力行全体をそのまま出力する。「print $0」と同等。 | |
print 値,値… | 変数の値や文字列を出力する。カンマで値を並べると、OFSの文字で区切られて出力される。 |
printf "書式",値… | C言語のprintfと同様の書式で出力する。 C言語と異なり、%dや%sといった書式指定に応じて 値が数値や文字列として扱われる。 |
if (〜) { 〜 } | C言語のif文と同様。 |
next | 次の入力データ行に移る。 (現在の入力行に対する残りのプログラムはスキップされ、次のデータ行が先頭のプログラムから適用される) |
exit 値 | 入力ファイルの処理を終了する。「値」は、awkのリターンコードとなる。 |
BEGIN { FS = ","; OFS = ","; ret_code=0; } $2 == "localhost" { print $1,"127.0.0.1"; ret_code++; next; } { print } END { exit ret_code; }
$0は入力データの1行全体の文字列で、$1,$2…は入力行をスペース(FS参照)で区切った単語(文字列)を表している。
$1や$2に値を代入すると、$0も置き換わる。その際には、OFSで区切った形式となる。
元の文字列が複数のスペースで区切られていたとしても、OFS1文字分になる。
「$」の直後には、数値だけでなく 変数や式も使用可能。$nとか$(n-1)とか。
デフォルトで、以下のような変数が定義されている。
変数名 | 内容 | デフォルト値 |
---|---|---|
FILENAME | 入力ファイル名 | 標準入力からの場合は、「-」 |
FS | フィールドセパレーター。入力時の$1や$2の区切り | 空白とタブ |
OFS | 出力フィールドセパレーター | 空白 |
NF | 現在のレコード(入力行)のフィールド数 | |
NR | 現在のレコード(入力行)の行番号 | |
RS | レコードセパレーター | 改行 |
ORS | 出力レコードセパレーター | 改行 |
複数行にわたるデータを1行にまとめてカンマ区切りで出力する例。[2014-05-01]
ORS(出力レコードセパレーター)を空文字列にすると、printで出力したときに改行されなくなる。
$ awk 'BEGIN { ORS=""; SEP="" } { print SEP$0; SEP="," }' input.txt
デフォルトで、以下のような関数が使える。
関数名 | 内容 |
---|---|
substr(文字列,位置,長さ) |
部分文字列の取得。位置は1から。 |
index(文字列,探索文字列) |
文字列の中にある、探索文字列の位置を返す。[2014-05-01] 先頭にあれば1が返る。見つからなければ0が返る。 |
length(文字列) |
文字列の長さの取得。 |
文字列 文字列 |
スペース区切りで文字列(変数)を並べると、文字列を結合する。(いわゆるconcat) |
int(数値) |
小数点以下切り捨て。 |
関数はfunctionで定義できる。[2011-12-26]
条件(パターン)の並びと同列の位置に書く。
function 関数名(変数名, …) { 〜処理〜 }
#呼び出す例 { 関数名(値, …); }