このスクリプトの解説を続けます。
{gsub(/"/,"")}
{gsub(/[ ][ ]+/,"")}
{print}
2行目の{gsub(/[ ][ ]+/,"")}はもう少し複雑です。//の中が一文字ではな
くて「二つ以上連続した半角空白」を意味する表現になっています(脚注1)。
カンマの後ろは1行目と同じで何も文字を指定していません。対象文字列の指
定も省略しているので結局「二つ以上連続した半角空白をレコードから消去し
なさい」という意味です。
ここまでで置換の処理はできました。しかし「sub, gsubがやるのはここま
でです」。これは大事なことで、この関数は対象文字列(この場合は$0)を書
き換えますが、結果の出力までは面倒見てくれません。またこの関数が返す値
も「置換された文字列そのもの」つまり「作用の結果を返すのではなくて」、
「いくつ置換したか」です。したがって置換した結果を得るには{print}で明
示的に出力してやらねばなりません。printはもうお馴染みで、このように単
独で使うと$0を出力します。
以上より、このスクリプトの出力はこんな感じです。
960105,19,960001,森田健作,M, 57,6,0,0,960105,7.8,1.69,25,21,333,138,25 ,5.2,0.6,19.4,4.1,223,80,140,0.1,5800,514,15.9,48.4,29.1,83 960105,20,960002,和田孝雄,M, 56,6,0,0,960105,7.1,1.96,23,32,225,118,23, 2.6,0.6,21.0,5.8,163,50,204,0.1,6700,543,17.0,49.3,21.6,78(注)70桁で改行しています。
前々回に「関数の"作用"と"返す値"は区別せよ」と書いたのはこういうこと
です。sub, gsubの作用は「文字列の置換」で、返す値は「置換した個数」で
す。関数の作用で置換された文字列そのものを返すわけではありません。しか
も文字列は見えないところでちゃんと置き替わっています。
例えば次のスクリプトを実験してみてください。
BEGIN{
a="Hellow Miniren net members!";
print a;
b=sub(/Miniren/,"min-min",a);
print b;
print a;}
出力はこうです。
Hellow Miniren net members!
1
Hellow min-min net members!
print bでなんとなく Hellow min-min net members! と出力されそうですが
(と思うのは私だけ?)、実際は 1 とでるだけです。
関数の作用(およびその結果)と返り値の関係は混乱しがちなところですか
ら、くれぐれもご注意ください。
(脚注1)
このような一連の書き方を「正規表現」といいます。以前ちょこっと紹介し
たことがあります。後に詳しく触れますので当面は読み飛ばしていただいて結
構です。
初出 NIFTY-Serve「みんみんネット」1996/09/18 (Wed) 14:00:53