《スクリプトファイルの作成》

 zenkei1.awkの製作に掛かろう・・・

パスの通ったところに作るのだが・・・

環境変数 AWKPATH は設定してあるだろうか?

ジャバの使っているwin2Kの場合は・・・

マイコンピュータのプロパティ>詳細>環境変数で設定できる。

ここで設定しておけば、AWKを呼べば、このディレクトリの中から、

探してくれるので、スクリプトファイルをここに書いておけば、

おっけーだ。

 書き出す前に、すこしAWKの動き方を説明しておこうと思う。

特にベーシックとか経験があると、かえって あれ? と、

思ったりするかもしれないので・・・

 外部変形で使うスクリプトは普通・・

AWK (-f)スクリプトファイル 読み込みファイル > 書き出しファイル

となっていて・・・スクリプトファイルは・・

BEGIN{・・・・}

{・・・・・}

END{・・・・}

function **(*){・・・・}

ってな、体裁を持つ事が多い。

 スクリプトが呼ばれると、まず BEGIN の{・・・・}が実行される。

その次に、読み込みファイルから1行持ってきて{・・・・}が実行される。

これは、1行ごとに実行されるので、{・・・・}の部分は、読み込みファイルの

行数回実行される。(他の場所でも書いたかもしれないけど・・・)

 読み込まれた1行は特別な変数$0に入っていて・・・1行を半角スペースを区切り

として、文節に分けて・・各文節が$1・$2・・・と言う風に格納されている。

 読み込みファイルを読み終えたら、END{・・・・}が実行される。

function **(*){・・・・}は関数の宣言で、スクリプト中のどこからでも、

呼び出す事ができる。スクリプト中に、print/printf とかの出力先省略の出力命令

があれば、その出力が、書き出しファイルに書き込まれるという風になっている。


 今回の場合、前処理(BEGINの節)は取り立てて必要ないと思うのだが・・

BEGIN{
# ***********************************************
# 文字種の変更をする。cnf=1 しないcnf=0
cnf=1
# 変更する場合の文字種
hcn="cn3"
# **********************************************
}

 とでもして文字種を変えるか変えないか、ここを訂正すればできるようにしておこう。

もちろん、Jww画面内で指示するようにバッチを書くこともできるが・・・

しょっちゅう変えたり変えなかったりしないんだったら、ここで変更する事にしたほうが、

全体としてのパフォーマンスはよいだろう。

 次は、読み込みファイル(jwc_temp.txt)の各行が送られてくる事をイメージして・・・

書き進む事になるが・・・JWW_SMPL.BATは脇に開いてるよね(^^;;?

{
if(/hq/){print"hd";print"h# 半>全 四則記号 書き換え";next}

 hqはそのままjwc_temp.txtに返すと未実行になるし・・

第一、文字列の書き換えなので、入力に使った文字には消えてもらうので、

hdを返すようにします。また、ここのnextは次の行の処理に移れ!と言うこと。

なので、hqで始まる行は以下の処理には行きません。

if(/^cn/){if(length($1)==3){cn=$1}}
if(/^ch/){syori();}
print
}

 最初のf(/^cn/)の部分は、文字種を一時的に変えた場合に、基に戻すため、

いつも有効な文字種を覚えておくためのものです。

 最初がchの時の処理を書きます。cn・chの意味は、バイブルで・・・

よく使う・・・例えば・・・if(/^cn/)は、cnで始まる場合は・・

と言う意味です。

 ここは、練習と言うことでもあるので・・処理は関数syori()をこさえて、

そこで行う事にします。

 syori()で文字列が入っている$6を直接変更する事にしておけば・・・

print 文で書き出せばよいでしょう。また、/hq/でも/ch/でも無い部分は、

このプリント文で順番に出力されるので、例えば・・レイヤが異なるところに

複数の数式があっても、それらのレイヤなどが乱れないようになります。

 要するに・・hq のところと、ch のところ意外は、そのまま書き出そう・・

ってことです。

END節は・・・今回特に書くことも無いと思うので、なしにしますか・・・

 ここまでの作業の確認のためにも・・・

function syori(){
$6="\"test"
}

 として・・実行してみましょう。どうですか?

数式がtestに変わったでしょうか?

うまく動かなかった場合は・・・バッチファイルの@echo off 行を削るか、

rem を頭に付けておいて・・・AWK行の下にpause を入れて実行すると、

どこでつまずいてるのか・・とか、エラーメッセージとかが、見られます。

全角のスペースがスクリプトのあってはいけないところにあったり・・

;が:だったり・・・その辺を見直してください。

 さあて、ここからが本番・・・かな?

さて、計算なんだけど・・・jwc_temp.txtから読み込んだ文字列は

文字列であって、数値やAWKの文では無いわけで・・・

いかに、文字・数値をあいまいにできるAWKといえども・・・

ans=0+(substr($6,2))とかやっても・・・4*8/5 として・・・

ansは4になってしまう。(エラーにならないのがすごい(^^;;)

 他のソフトに渡して・・・って、手もあるけど・・・

ここは、AWKでべつのAWKをこさえて・・・パイプで・・・

 とりあえず・・・

function syori(){
tmp=substr($6,2)
ans= keisan(tmp);
siki=tmp "=" ans
$6="\"" h2z(siki)
}

 として、ここでは、計算はkeisan()に半角全角変換はh2z()というふうに、

別の関数に任せましょう。

 で、keisan()を書くのですが・・・ここは少しトリッキーな処理を

してみましょう。(この御題を考えた時から考えてたんだけど・・

うまくいくかどうか・・)

function keisan(atai_in){
print "BEGIN{print " atai_in "}" > "z_k_tmp.awk"
close("z_k_tmp.awk")
com= "mawk32 -f z_k_tmp.awk"
com|getline rets
close(com)
system("del z_k_tmp.awk")
return rets
}

 ここで やっているのは・・AWKに計算させるために1行のAWK

BEGIN{print 式} というのを、z_k_tmp.awkとしてこさえといて

|”パイプの処理”と言うのを使って、それを実行して

結果をretsと言う変数にしまっといて・・・

最後に、z_k_tmp.awk を削除する・・・ってことをしています。

 最後に全角半角の変換をしましょう。

と、言っても・・・昔作った関数を使ったので・・・(^^;;

function h2z(str)
{
ret=""
old="0123456789*+-/=.,abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
new="0123456789×+−÷=.,abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
for (i=1;i<=length(str);i++)
{
char=jsubstr(str,i,1)
po=jindex(old,char)
if (po==0){ret=ret char}
else {ret=ret jsubstr(new,po,1)}
}

return ret
}

 ようは、関数に渡された文字列を頭から1文字づつoldと言う文字列(半角の文字)と比べて、

該当するものがあったら、その場所とnew(全角)の同じ場所にある文字と取り替えるという事を

しています。アルファベットの部分は今回は使いませんが・・・まぁあっても害は無いでしょう。

 おっと、いけない。文字種を変えるあたりの事を忘れてました。

if(/^ch/){syori();} のところを直して対応しましょう。

数式だけを範囲指定してもらうとすれば・・・

if(cnf==1){print hcn;cnf=2;}
syori();}
print
if(cnf==2){print cn;cnf=1}

 とでもしておきましょう。

 一応、完成したので、テキストとして、見えるようにしておきますね。

 バッチ スクリプト こぴぺしてお使いください。

 さて、HTM文書を作りながらこさえたので・・・半日かかってしまいましたが・・

これを公開する事ができるでしょうか?(ここは、外部変形の練習としての公開だよ)

答えは否です。ざっと考えて・・数式中にスペースがあったら・・それ以降は反映してない。

数式の最後に=とか入ってると、計算できない。1,800とか様に","があると計算できない。

答えが1000を超えても","が入らない。そもそも、ドキュメントを書いてない。

これをクリアしようと思うと1日たっぷり掛かります。

 でも、自分で使うには十分使えると思いませんか?

それに、自分で作ったのであれば・・この答えの後ろに50間を空けて、答えの1/7を書き、

そこからまた50に1/20へてから1/50を書かせるようにだって、簡単な事だと思います。

小数点とカンマだけ半角にとか・・数字も半角とか・・ちょちょいのちょいだよね。

3桁ごとに","をいれる関数をもっていれば、それだって簡単だし・・・

 他の方が作ったものでも、簡単なものなら解読して、自分の使いやすいように

改造してしまいましょう(作者が許している場合ってことですよ。)

楽をしたかったら・・少し努力をしましょう。

 この節に書いたバッチとスクリプトは自由に改変してかまいません。

楽しんでくださいね。


next:《外変の為のバッチファイル超入門》