AWK DOCUMENT


AWK.AWK

# arrayに代入演算子 "=" は通じない
#BEGIN{
# ar[1]="a";
# ar[2]="b";
# ar[3]="c";
# br = ar;
# for( i = 1; i <= 3; i++ )
# print "br" i "=" br[i];
#}

# 普通の返値は代入できるが...(次項へ続く)
#function foo( b){
# b = "b";
# return b;
#}
#BEGIN{
# a = foo();
# print a;
#}

# array の返値は代入できない
#function boo( b ){
# b[1] = "a";
# b[2] = "b";
# b[3] = "c";
# return b;
#}
#BEGIN{
# a = boo();
# for( i = 1; i <= 3; i++ )
# print "a[" i "]=" a[i];
#}

# "~" 演算子の引数は左項が普通のテキスト,右項が正規表現でなければならない.
#BEGIN{
# if( "test" ~ /^test/ )
# print "r:text, l:rexp"; #マッチする
# if( /^test/ ~ "test" )
# print "r:rexp, l:text"; #マッチしない
#}

# NULL オブジェクトは "" である.
# [boo.doc]
# aaa,,aaa
# [command line]
# jgawk -F',' '{if($2=="") print "null"}' testfile.doc

# 以下の挙動は普通だが...(続く)
# [foo.doc]
# 1
# 2
# 3
# 1
# 2
# 3
# [command line]
# jgawk -f awk.awk foo.doc
#/2/,/1/{ # filter A
# print "contents:" $0
#}
#/1/{ # filter B
# print "saved top:" $0;
#}
# [result] (行番号は後から付加)
#>jgawk -f awk.awk foo.doc
#1. saved top:1
#2. contents:2
#3. contents:3
#4. saved top:1
#5. contents:1
#6. contents:2
#7. contents:3
#
# [conclusion]
# fillter A のマッチング領域は /2/ から始り /1/ で終る領域.fillter B は
#/1/ にマッチする行のみである.
# 結果を見ると確かにその通りに機能している.しかし,行番号 4 と 5 のあた
#りに,面白い挙動が見られる.スクリプト内部では,fillte A ,fillter B の順
#番に定義したが,その両者が同時に起動するポイントである,2番目の "1" が書
#かれている行では,fillter B の方が先に実行され,その後に fillter A が実行
#されていることがわかる.つまり,フィルタの定義はその実行される順番には関
#係ない.
# さらに,興味深い挙動が次の項で示される.

# しかし,以下のように /1/, /2/ を変数に代入して使うと,上記の挙動とは違
#う動作をしてしまう.
# [testfile.doc]
# 1
# 2
# 3
# 1
# 2
# 3
# [command line]
# jgawk -f awk.awk testfile.doc
#BEGIN{
# a = "1";
# b = "2";
#}
#b,a{ # filter A
# print "contents:" $0
#}
#a{ # filter B
# print "saved top:" $0;
#}
# [result]
#>jgawk -f awk.awk foo.doc
#contents:1
#saved top:1
#contents:2
#saved top:2
#contents:3
#saved top:3
#contents:1
#saved top:1
#contents:2
#saved top:2
#contents:3
#saved top:3
#
# [conclusion]
# filter A/B 自体の定義は前項のものと同一,マッチング領域も同一.だが,そ
#のマッチング領域の「指定方法」が,正規表現の直書きから,変数からの参照へ
#と変っている.
# これだけの違いで,Filter A/B のマッチング領域が,両者に指定したマッチン
#グ領域の論理和をとった領域に変更されてしまっている.
# こいつには,はまりました.(^^;

# 未定義オブジェクトは, !object 論理演算で true になる
#BEGIN{
# if( !UNKNOWN ) print "UNKNOWN is false";
# else print "INKNOWN is true";
#}


# AWK のエラー出力: "record not terminated" 編
#
#jgawk.exe: warning: record not terminated
# input line number 60, file `.\lib\distml2.awk'
# source line number 10, file `awkpp.awk'
#
# これは,ファイルの一番最後の行が,改行のみで終っていないためです.なぜ
#なら,RS( Record Separator ) が,"\n" (改行)のデフォルトであるとして,改
#行を \n,EOF を[EOF]とすると,
#
#----------< ここから例示 >---------------------------------------------
#これは "record terminated" な行です.\n
#これは,ファイルの一番最後にありがちな,"record not terminated" な行です.[EOF]
#-----------------------------------------------------------------------
#
# つまり,行のセパレータである "\n" が,一番最後の行には存在せず,かわり
#に EOF が居座っているのです.これを避けるためには,以下のようにします.
#
#----------< ここから例示 >---------------------------------------------
#これは "record terminated" な行です.\n
#この最後の行も "record terminated" な行となりました.\n
#[EOF]
#-----------------------------------------------------------------------

# getline のバグ? →(ちがった.結果から言うと,ただの勘違い.最後を見
#てください)
#
# 以下のようにして,getline を同一ファイルに対し繰返したとき,連続して読
#込めないときがある.
# 確かめ方は,下記のスクリプト部分をコメントアウトし,コマンドラインで,
# jgawk -f awk.awk < con
# を,命令して,標準入力として,"read" を打込めばよい.そのとき,下記のよ
#うに,getline が起動され,カレントディレクトリのファイル foo.doc が読込ま
#れその内容が標準出力に表示される.
# ためしに,やってみると,"read" を最初にやったときは,うまく foo.doc を
#読込まれるはず(カレントディレクトリに foo.doc を用意しておくのをお忘れな
#く).だが,二回目,三回目,それ以降も同じく,"read" が成功することはない.
# どして?close 文によって,ファイルハンドルは解放しているはず.
# また,ファイルネームを直接渡す,"READ" の方は,「最初から "READ" だけ繰
#返す」と,何度でも読込みに「成功する」.しかし,始めに "read" を入力し,
#そのすぐ後に "READ" を入力すると,読込みに失敗する.
# 以上のように,挙動が変.なぜ?
# 一応しょうがないから,ファイルから読込むときには, "READ" の方の方法を
#採ることによって,この問題を回避はしているが...
#
#BEGIN{
# filename = "foo.doc";
# dirpath = ".";
#}
#/read/{
# # indirect indicatio to foo.doc
# while ( ( getline < (dirpath "\\" filename) ) > 0 ){
# print $0;
# }
# close( (dirpath "\\" filename) );
#}
#/READ/{
# # direct indication to foo.doc
# while ( ( getline < ".\\foo.doc" ) > 0 ){
# print $0;
# }
# close( ".\\foo.doc" );
#}
#
#[最後]
# ...うっそでーす! 上の奴はちゃんと動きまーす.close 文の引数を,間違
#えてました.具体的には,
#
# close( (dirpath "\\" filename) );
# と,しなければならないところを,
# close( (dirpath "\\" finename) );
# ^^^^ !
# と,スペルミスをしておりました.これでは,ファイルハンドルを解放できる
#わけありませんね.


## awk のアドレス指定子に,変数を指定しても,きちんとマッチングをやってく
##れない.具体的には,変数の中身に書いた文字列とは関係なく,全ての行とマッ
##チするようになってしまう.
#BEGIN{
# REXP = "^aaa"; # すべての文字にマッチ
## REXP = "/^aaa/"; # すべての文字にマッチ
## REXP = "\/^aaa\/"; # すべての文字にマッチ
## REXP = /^aaa/; # 例外)どの文字にもマッチしない.実は中身は数値の 0
# print "REXP = " REXP;
#}
#/bbb/{
# print "this is /bbb/ matched.";
#}
#REXP{
# print "this is REXP (=" REXP ") matched.";
#}
#{
# if( $0 ~ REXP ) # これは期待したとおりのマッチをしてくれる
# print "REXP matched in if-condition of $0 ~ REXP. : $0=" $0 " REXP=" REXP;
#}

# Vz のコマンドラインで,以下のスクリプトを実行すると,ハングする...と
#おもいきや,全然大丈夫..\lib\periph\method.awk の help_reply では同じこ
#とをやっているのに,ハングしてしまう.なぜ?
# スクリプト自体は,jgawk から子プロセスの jgawk を呼んでいるだけ.
#{
# system( "jgawk '{print \$0}\' < foo.doc" );
#}

foo.doc

1
2
3
1
2
3

boo.doc

aaa,,aaa

これらのファイルをダウンロードしたいかたは、こちら