GAWK 数値にカンマを付加する
addcomma()
AWK の教科書「プログラミング言語AWK」に掲載されている addcomma() に手を加えて、筆者にとって使い勝手の良いものにしました。
テキスト全体に適宜カンマを付加する
addcomma_test.txt
ex1 文章中の数値
この都市の人口は984586人であり、世帯数は667512世帯である。
先月までの収支は-015612345円です。!訂正-156123450円
新商品「RZ-11000RS」の発表は、2022/10/11を予定しています。(¥687000)
具材と1200ccの水を鍋に入れ、およそ1000ccになるまで煮込む。
1載(100000000000000000000000000000000000000000000)
ex2 数式中の数値
12000.005+13200.01=25200.015
12000.005 + 13200.01 = 25200.015
ex3 認識番号他
〒 345-6666
phone 090-999-9999
mail hoge179238@dodomo.com
version gawk5 (5.1.2.7200)
csv 1024,2048,3072,4096 => ssv 1024 2048 3072 4096
ex4 表
43276147 39821106 3455041 55811969
44246688 40691869 3554819 55364197
45362672 41687125 3675547 54952108
46999468 43126352 3873116 54594744
実行結果
awk_addcomma.awk
ACTION_01
1 : # awk_addcomma.awk
2 : # addcomma()とgetnum()を検証する
3 : # ファイルに存在する数値を走査し適宜カンマを付加
4 : # 試験コマンド gawk -f awk_getnum.awk addcomma_test.txt
5 :
6 : #. ACTION_01:数値検索とカンマ付加
7 : {
8 : str = $0;
9 : newstr = "";
10 : do {
11 : tnum = getnum(str, startpos, nextpos, 1); #mode=1 動作
12 : if (tnum) { #数値発見/有効数値
13 : tstr = addcomma(tnum);
14 : newstr = newstr substr(str, 1, startpos[0] - 1) tstr;
15 : str = substr(str, nextpos[0]);
16 : }
17 : else if (startpos[0]) { #数値発見/無効数値
18 : newstr = newstr substr(str, 1, nextpos[0] - 1);
19 : str = substr(str, nextpos[0]);
20 : }
21 : else print newstr substr(str, 1); #数値がなくなった
22 : } while (startpos[0])
23 : }
getnum()
24 : #. getnum(): 文字列から恣意的または妄信的に数値を取得
25 : # 戻値: 文字列としての数値(指数表記除外) or ""
26 : # str:in: 文字列
27 : # spos:out: 数値候補位置(先頭)
28 : # npos:out: 次候補検索位置(検査済み位置 + 1)
29 : # mode:in: 0 あらゆる数値を拾う 1 少しスマートに数値を拾う
30 : function getnum(str, spos, npos, mode, rlen, num) {
31 : #数値候補を検索
32 : if (mode) spos[0] = match(str, /[a-zA-Z%]?[0-9.,\-+*/\^=><]+/);
33 : else spos[0] = match(str, /-?[0-9]+\.?[0-9]*/);
34 : if (!spos[0]) return "";
35 :
36 : rlen = RLENGTH;
37 : npos[0] = spos[0] + rlen;
38 : num = substr(str, spos[0], rlen); #候補数値
39 : match(num, /-?([1-9][0-9]*|0|([1-9][0-9]*\.|0\.)[0-9]+)/); #精査
40 : if (RLENGTH == rlen) return num; #有効数値
41 : else return "";
42 : }
addcomma()
43 : #. addcomma(): 3桁毎にカンマ付加
44 : # 戻値: カンマを付加した数値(文字列型)
45 : # x:in: 数値(文字列型) addcomma("9999")
46 : # 別関数等で引数チェック(数値)が必要
47 : function addcomma(x, num, fms, pos, itg, flt) {
48 : if (x !~ /^-/) { num = x; fms = 0; }
49 : else { num = substr(x, 2); fms = 1; }
50 :
51 : if (pos = index(num, ".")) {
52 : itg = substr(num, 1, pos);
53 : flt = substr(num, pos + 1);
54 : }
55 : else itg = num ".";
56 :
57 : while (itg ~ /[0-9][0-9][0-9][0-9]/)
58 : sub(/[0-9][0-9][0-9][,.]/, ",&", itg);
59 :
60 : (pos) ? num = itg flt : num = substr(itg, 1, length(itg) - 1);
61 : (fms) ? num = "-" num : 0;
62 : return num;
63 : }
:
:
:
:
:
数表のみにカンマを適用するのであれば、getnum()は重いので、以下のように使用すると、軽くなります。当社比 1/5。addcomma() は引数の数値チェック必須です。
上記と違い、数値として扱いますので、53bit までとなります。($i == $i + 0)
1 : # awk_addcomma_s.awk
2 : # 数表専用
3 :
4 : #. BEGIN: 加工後のセパレータ
5 : BEGIN {
6 : sep = " ";
7 : }
8 : #. ACTION_01: 数値チェックしてカンマ付加
9 : {
10 : str = "";
11 : for (i = 1; i < NF; i++) {
12 : if ($i == $i + 0) str = str addcomma($i) sep;
13 : else str = str $i sep;
14 : }
15 : if ($NF == $NF + 0) print str addcomma($NF);
16 : else print str $NF;
17 : }