@WIKI

Awkについて

最終更新:

atyou

- view
管理者のみ編集可
awk とは
awk(「オーク」と呼びます)とは、フィルタの一種で、パターンを検索し、
それに対して対応する処理(アクション)を行なうものです。フィルタとして、今まで grep や sed を学んで来ましたが、 awk はより強力になっています。例えば、awk は計算機能をもっていて簡単な表計算に似たようなことも出来ます。
(このようなことから awk は万能フィルタと呼ばれていて、 awk をマスターすれば、一般的なプログラミング言語などよりも簡単につくれるプログラムもたくさんあります)


awk は、他のフィルタと同様に指定されたファイル名を入力として、ファイルの中身を一行づつ処理して、
標準出力に出力します。
このとき元となったファイル自体に変更がくわえられないことも、他のフィルタと同様です。

AWK の簡単な説明     Last modified: May 15, 2002
--------------------------------------------------------------------------------

 AWKは起動されると先ずAWKプログラムソースを読み込む。AWKは読み込んだプログラムを内部表現にコンパイルした後,指定された入力ファイルを順に処理していく。入力された各行についてAWKはその行がAWKプログラムに指示されたパターンに合致するかどうかを調べる。そしてパターンが合致すればそれに対応する作用ブロックが実行される。

 また,AWKは各行を読み込む度に,それをフィールドに分割する。フィールド区切り子としては予約変数FSの値が使用される。もしFSの内容が1文字だけならば各フィールドはその文字で分けられる。そうでなければFSは正規表現であると見なされる。

AWKのプログラム要素

 AWKプログラムの構成は次のようになっている。

pattern { action statements }
function name(parameter list) { statements }

パターン

BEGIN
END
BEGINとENDは特別なパターンであり,入力に対して反応するのではない。
パターンBEGINを持つ作用は全て集められひとつのBEGINブロックを形成する。
それは入力が始まる前に実行される。
同様にパターンENDを持つ作用もひとつにまとめられ入力が終わったときに(またはexit文が実行されたときに)実行される。
パターンと作用
AWKは行型(line oriented)の言語である。
先ずパターンが先にきてその後ろに作用を記述する。
作用は{と}で囲む。パターンもしくは作用のいずれか一方は省略できる。
パターンが省略されたときはその作用は入力された全ての行に対して実行される。
一方,作用を省略することは,
{ print }
と同義である。
すなわちその行全体を出力する。
予約変数

FILENAME  現在処理中の入力ファイルの名前。
FNR  現在処理中の入力ファイル中でのレコード番号。
FS  入力フィールド区切り子。デフォルトでは1個の空白文字。
NF  現在処理中のレコードに含まれるフィールドの個数。
フィールド
入力されたファイルの各行は,FSに従ってフィールドに分解される。各フィールドはその位置に応じて$1,$2 等として参照される。$0 は入力行全体を保持している。
配列要素
角括弧([と])中の式の値(文字列型)によって指定される。例えば配列A(2,4)はAWKではA[2,4]と表される。
制御文

for (expr1; expr2; expr3) statement
exit [ expression ]
printf fmt, expr-list
式(の並び)の値を書式付きで出力する。
関数
AWKに於ける関数は次の形で定義される。
function name(parameter list) { statements } 関数はあまり多く用意されていない。例えば,絶対値をとる関数なども,自分で作らないといけない。
関数はパターン-作用対の中の作用ブロックの中から呼ばれることによって実行される。
関数呼び出し時の実引数は,関数で宣言された仮引数に渡される。


AWKの組込み変数     Last modified: May 15, 2002
--------------------------------------------------------------------------------

 AWKが用意している主な組込み変数は以下のようなものがある。これらの変数は全て大文字である。 FS 入力されたデータをフィールドに区切るときの,フィールドの区切り文字を指定する。デフォールトは空白1個である(FS=" ")が,この設定は空白のみならず,連続する複数個の空白やタブを1つのフィールド区切り文字として認識し,行頭や行末の空白タブは無視する。例えば,フィールドの区切り文字がカンマであるときには,FS="," のように再定義することができる。
OFMT print文で数値を文字として表示するときに使われる書式を表す。デフォールトは OFMT="%.6g" である。すなわち,有効数字6桁で表現する。これを,CONVFMT="%10.5f" などのように再定義することができる。
FILENAME AWKが現在入力対象としているデータファイル名が格納されている。
FNR AWKが現在入力しているファイルのレコード番号(何行目か)を表す。
NR AWKが現在までに入力したレコード数(何行読んだか)を表す。
NF 読み込んだ入力行に含まれるフィールドの数を表す。

AWKプログラム
 「AWKプログラム」は、「パターン-アクション規則」と「関数定義」の並びである。

パターン{アクション}
パターン{アクション}
...
function 名前(引数の並び){ 文 }
function 名前(引数の並び){ 文 }
...

パターン-アクション規則や関数定義の前後に空行を挿入してもよい。関数定義はどこに記述してもよい。
 入力レコードをひとつ読む度に、パターン-アクション規則のパターンが順に検査される。パターン-アクション規則は、パターンが真となるレコードに対して、対応するアクションが実行される。
 パターンあるいは{アクション}のいずれかを省略することができる。パターンを省略するとすべてのレコードにアクションが実行され、{アクション}を省略するとパターンが真となるレコードを表示する。

パターン
 「パターン」は次のいずれかである。

BEGIN
END

/正規表現/
パターン,パターン

アクションと文
 「アクション」は文の並びである。
 文は次のいずれかである。


制御文
入出力文
{文の並び}
空文

文は改行か';'で区切る。';'が単独で用いられると、空文を表す。文の前後には空行を挿入してもよい。
 長い文は、行末に'\'を置いて次行に続けることができる。", { && || do else"のあと、および"if( )","for( )"のあとは、'\'を置かずに改行しても継続とみなされる。

制御文
 制御文は次のいずれかである。

break
continue
do 文 while(式)
exit
exit(式)
if(式) 文
if(式) 文 else 文
for(式;式;式) 文
for(変数 in 配列) 文
next
return
return(式)
while(式) 文

 if-else文において、最初の文がelseと同じ行にある場合、この文は';'で終了するか"{ }"で囲まなければならない。


基本的な制御構造
文の種類 記法  
逐次構造(文の並び) {文1; 文2; ... 文n}  
選択構造(if文) if(式) 文  
選択構造(if-else文) if(式) 文1 else 文2  
ループ構造(for文) for(式1; 式2; 式3) 文  
ループ構造(while文) while(式) 文  
ループ構造(do-while文) do 文 while(式)  

入出力文
 入出力文は次のとおりである。

getline 入力レコードを"$0"にセット  
getline 式 0または1  
文の種類 書式 戻り値  
比較 式>=式 0または1  
式!=式 0または1  
式==式 0または1  
配列要素 式 in 式 0または1  
パターンの検査 式~/正規表現/ 0または1  
式!~/正規表現/ 0または1  
和 式+式 演算結果  
差 式-式 演算結果  
積 式*式 演算結果  
商 式/式 演算結果  
剰余 式%式 演算結果  
累乗 式^式 演算結果  
 +式  
 -式  
(式)  
文字列連接 文字式 文字式 文字列


組み込み変数
 次の組み込み変数が用意されている。

組み込み変数 値  
ARGC コマンド行の引数の数  
ARGV コマンド行の引数の配列  
FILENAME 現在の入力ファイル名  
ENVIRON["..."] 環境変数の値  
FS 入力のフィールドセパレータ(はじめはスペースまたはタブ)  
RS 入力のレコードセパレータ(はじめは改行)  
NF 現在レコードのフィールド数  
NR 現在の通算レコード  
FNR 現在の入力ファイルの通算レコード  
OFS 表示のフィールドセパレータ(はじめはスペース)  
ORS 表示のレコードセパレータ(はじめは改行)  
OFMT 数の表示のフォーマット(はじめは"%.6g")  
RSTART matchでマッチした文字列の開始位置  
RLENGTH matchでマッチした文字列の長さ  
$0 現在の入力レコード  
$1,...,$NF 第1フィールド,...,第NFフィールド


組み込み文字列関数
組み込み文字列変数 値  
gsub(r,s,t) 文字列tの中に現れる文字列rをすべて文字列sで置換する.置換した数を返す.tを省略すると$0が使われる.  
index(s,t) 文字列sの中の文字列tの位置を返す.tが現れない場合は0.  
jindex(s,t) 日本語文字列sの中の文字列tの位置を返す.tが現れない場合は0.  
length(s) 文字列sの長さを返す.  
jlength(s) 日本語文字列sの長さを返す.  
match(s,r) 文字列sが文字列rにマッチする位置を返す.マッチしないときは0.  
split(s,a,fs) fsをフィールドセパレータとして文字列sを配列aに分解し、フィールド数を返す.  
sprintf(書式,式) 書式で整えた式の並びを返す.  
sub(r,s,t) gsub()と同様.ただしはじめの1回だけ置換する.  
substr(s,i,n) 文字列sのi番目から始まるn文字を返す.  
jsubstr(s,i,n) 日本語文字列sのi番目から始まるn文字を返す.


組み込み算術関数
組み込み算術変数 値  
atan2(y,x) atan(y/x)で-π~πの値.  
sin(x) sin関数  
cos(x) cos関数  
exp(x) exp関数  
log(x) 自然対数  
sqrt(x) 平方根  
int(x) 小数点以下を切り捨て  
rand() 疑似乱数 0以上1未満  
srand() 乱数の初期化


書式変換
 printfとsprintfの中では次のような変換が利用できる。ここでは例で示す。

記法 値  
printf("|%c|",65)  |A|  
printf("|%d|",65)  |65|  
printf("|%5d|",65)  | 65|  
printf("|%05d|",65)  |00065|  
printf("|%f|",65)  |65.000000|  
printf("|%5.1f|",65)  | 65.0|  
printf("|%e|",65)  |6.500000e+01|  
printf("|%5.1e|",65)  |6.5e+01|  
printf("|%g|",65)  |65|  
printf("|%o|",65)  |101|  
printf("|%s|","hirosaki")  |hirosaki|  
printf("|%10s|","hirosaki")  | hirosaki|  
printf("|%-10s|","hirosaki")  |hirosaki |  
printf("|%.4s|","hirosaki")  |hiro|  
printf("|%10.4s|","hirosaki")  | hiro|  
printf("|%-10.4s|","hirosaki")  |hiro |  
printf("|%%|")  |%|


正規表現
 例で正規表現の記法を示す。通常これらの組み合わせとなる。

記法 値  
A Aそのもの(以下の特殊文字を除く普通の文字)  
\\ \そのもの  
\" "そのもの  
\t タブ  
\n 改行  
\f フォームフィード  
\b バックスペース  
\033 8進数033  
^a 文字列の先頭が'a'  
a$ 文字列の末尾が'a'  
. 任意の1文字  
[abc] 'a''b''c'のどれか1文字  
[^abc] 'a''b''c'以外の1文字  
[a-e] 'a''b''c''d''e'のどれか1文字  
[^a-e] 'a''b''c''d''e'以外の1文字  
a* 0個以上の'a'の並び  
a+ 1個以上の'a'の並び  
a? 'a'が1個あるいは0個  
abc|de "abc"または"de"


正規表現とは     Last modified: May 15, 2002
--------------------------------------------------------------------------------

 おおざっぱに言えば,正規表現 regular expression とは,ある規則に従う文字列を指定(識別)するための規則である。

 例えば,「Aで始まって9で終わるような文字列」とか,「文字列の先頭にアルファベットがある行」というような指定をしたいことがある。このようなときには,可能な全ての場合を列挙するわけにはいかないので,特定の文字で一般的な文字列を指定する方法をとることになる。

 正規表現が使われるのは文字列を処理する関数やパターンの指定のときである。例えば, $0 ~ /this is reg\. exp\./ というパターンは,入力した行の中に,’this is reg. exp.’という文字列が含まれているとき「真値」を返す。

 正規表現に使われる文字(例えば,上の例の \ など)とその意味は以下のようになる。

^ 文字列の先頭を表す。
例:^abc というのは,先頭の3文字が abc である文字列にマッチする。
$ 文字列の末尾を表す。
例:987$ というのは,最後の3文字が 987 である文字列にマッチする。
. 改行文字を除く任意の1文字に一致する。
例:a.x は a とx の間に任意の1文字がある3文字(たとえば ayx,a9x など)にマッチする。
[ ] [ ]に含まれる1文字にマッチする。連続する文字は-でつないで指定する。
例:[abC] は,a, b, C のいずれかを表す。[0-9]は,数字1文字を表す。
[^ ] [ ]に含まれない1文字にマッチする。
例:[^0-9A-Za-z] は,英数字以外の1文字にマッチする。
| 「または」を意味する。
例:^A|[0-9] 行頭の A か 数字にマッチする。
* この記号の前にある文字の0回以上の繰り返しを意味する。
例:ab*x は ax,abx,abbx,abbbx などにマッチする。
+ この記号の前にある文字の1回以上の繰り返しを意味する。
例:ab+x は abx,abbx,abbbx などにマッチする。
? この記号の前にある文字の1回もしくは0回の繰り返しを意味する。
例:ab?x は ax,abx のいずれかにマッチする。
\ この文字の後に続く文字をそのままの意味で使用する。
例:\. ピリオドを表す。\* アスタリスクを表す。
目安箱バナー