将阿拉伯数字转化为中文大写形式的AWK脚本
将阿拉伯数字转化为中文大写形式的AWK脚本
原来在w0rdpress上帖过的,本来想扩充成一篇教程再帖在这里的。但打了几个字就决定放弃了,实在是累啊……这里面用到了自定义的函数,大家可以参考一下。还有欢迎大家来信交流hq00e@126.com。
–
hq00e
这是一个将阿拉伯数字转化为相应的中文大写形式的gawk脚本。前几天有人问起能否用awk实现数字转中文大写,于是写了这个脚本。本来想是挺简单的,没想到修修补补的还折腾了一晚 :(
这里面用到了两个数组a和p,刚接触awk的人可以参考一下这里面数组的用法。个人认为使用数组可以大大地简化脚本。尤其是awk中对变量的类型没有严格限定,可以很容易地在数组的索引与值之间建立关联。
下面是脚本:
#!/usr/bin/gawk -f
# 1234567890 壹贰叁肆伍陆柒捌玖零
# 说明:单位以“亿亿”表示10的16次方,而“亿亿亿”表示
# 10的24次方,依此类推
# 自定义函数setunits():为数字增加中文单位
# setunits(起始位,结束位,亿的个数, ...局部变量)
# 一般以8 个为一个单位
func setunits(off1,off2,state, i,j){
for(i=off2;i>=off1;i--) {
if (off2-i==4) $i=$i "万"
else if($i!="0") $i=$i p[(off2-i)%4]
}
# 每8位state就增加1,用来控制单位中“亿”的个数。
j=state; while(j--) $off2=$off2 "亿"
# 退出条件
if (off1==1) return
else if (off1<=9) setunits(1,off1-1,++state)
else setunits(off1-8,off1-1,++state)
}
# 自定义函数conv_num():将数字转换为中文
# 定义局部变量i
func conv_num( i){
# 注意下面替换的顺序
sub(/0*\./,"点")
# 清除连续的0
gsub(/0000万0000[亿]+/,"")
gsub(/0000万/,"")
gsub(/0+亿/,"亿")
gsub(/0+万/,"万")
gsub(/0+/,"0")
sub(/^[亿万]+/,"")
#清除首尾的0
sub(/^00*/,"")
sub(/00*$/,"")
sub(/^$/,"零")
sub(/^点/,"零点")
# 替换阿拉伯数字为中文
for(i in a) gsub(i-1,a[i])
}
# 主程序体 -------------------------
# 设置栏位的输入和输出的分隔符为空字串
BEGIN{ FS=OFS=""
split("拾,佰,仟,万",p,",")
split("零,壹,贰,叁,肆,伍,陆,柒,捌,玖",a,",")
}
{ gsub(/,/,"") } #允许输入 123,456.789 的形式
# 验证输入。这里没有对多个小数点进行验证。
/^[-0-9][0-9.]*$/{
# 判断正负
isNeg=(sub(/^-/,""))
# 小数点前的数字进行单位设置
if (dotpos=index($0,".")) {
of2=dotpos-1
for (i=of2+2;i<=NF;i++) $i=a[$i+1]
}else of2=NF
if (of2>8) setunits(of2-7,of2,0)
else setunits(1,of2,0)
# 阿拉伯数字转为中文数字
conv_num()
# 还原正负号
if (isNeg && $0!="零") print "负" $0
else print
}
# 程序结束 -------------------------
将上面的脚本保存为”chfig.awk”(当然你可以随意地命名)。这是运行结果:
hq00e@somewhere ~ $ echo 98.76543210|gawk -f chfig.awk 玖拾捌点柒陆伍肆叁贰壹零 hq00e@somewhere ~ $ echo -10000234000.060|gawk -f chfig.awk 负壹佰亿零贰拾叁万肆仟点零陆零
[–结束–]
![hq00e[a]126.com](http://static.flickr.com/56/120355805_7079a475f9_m.jpg)


