Sample Site

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

実行結果

addcomma_01.jpg

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 : }