免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7733 | 回复: 14
打印 上一主题 下一主题

shell人民币大写转换 (含纯sed版) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-02 21:45 |只看该作者 |倒序浏览
在网上看到一个人民币大写的转换脚本,觉得好复杂,
试着sed写了一个,一定有不少错误而且也应该还能更简洁,请各位指正,谢谢
  1. [rockfall@Rocfall ~/tmp/sh]$cat Cmoney.sed
  2. #!/bin/sed -f
  3. #
  4. #        +------------------------------------------------+
  5. # 字母   |  k  | j  |   . |  b  |   c |   d  |  x  |   y  |
  6. #        +-----+----+-----+-----+-----+------+-----+------+
  7. #  表示  |  分 | 角 |  元 |  拾 | 佰  |  仟  |  万 |  亿  |
  8. #        +------------------------------------------------+
  9. #只做到亿,输入数据按标准的货币格式:xxxx.yy
  10. #2009-11-2

  11. /^[0-9]\+\.[0-9]\{2\}/{
  12.          s/\../&j/;                                 s/\..../&k/               #插入单位符号     
  13.          s/.\./b&/;                                 s/...\./c&/;
  14.          s/.\{5\}\./d&/;                      s/.\{7\}\./x&/;
  15.          s/.\{9\}\./b&/;                      s/.\{11\}\./c&/;
  16.          s/.\{13\}\./d&/;                            s/.\{15\}\./y&/;        
  17.         /^[a-z]*/s///;                    #去前面的重复字母,因为前面的处理会出现形状是两连续字母
  18.          s/\(0[a-u]\)\{1,\}/0/g ;    #去千万至万、千至元及角分之间的重复零
  19.             /0\+x/s/\0\+//;           #去掉万位前的重复零
  20.         /yx/s//y/;             #对万位的处理                                       
  21.         /0\+\./s//./          #去掉元前的重复零
  22.          /^\./s///              #不足元的,去掉元  
  23.         /0$/s///; /0k$/s///;          #对"分角"处理   
  24.         s/^0//;                 #删去开头的零,只有分时会出现
  25.        /[^k]$/s/$/z/            #在结尾加"整"字
  26.        y/0123456789/零壹贰叁肆伍陆柒捌玖/
  27.        y/kj.bcdxyz/分角元拾佰仟万亿整/
  28. }
  29. p
  30. [rockfall@Rocfall ~/tmp/sh]$cat data
  31. 121.15
  32. 100.20
  33. 100000.55
  34. 100100.53
  35. 100001000.19
  36. 0.12
  37. 1.01
  38. [rockfall@Rocfall ~/tmp/sh]$sed -nf Cmoney.sed data
  39. 壹佰贰拾壹元壹角伍分
  40. 壹佰元贰角整
  41. 壹拾万元伍角伍分
  42. 壹拾万零壹佰元伍角叁分
  43. 壹亿壹仟元壹角玖分
  44. 壹角贰分
  45. 壹元零壹分
复制代码
网上找到的
  1. #!/bin/bash
  2. #[email]penny_ccf@hotmail.com[/email]

  3. #it's ugly, but it works


  4. cconvert(){

  5. declare -a cnum;
  6. declare -a cmag;

  7. cnum[1]="壹"
  8. cnum[2]="贰"
  9. cnum[3]="叁"
  10. cnum[4]="肆"
  11. cnum[5]="伍"
  12. cnum[6]="陆"
  13. cnum[7]="柒"
  14. cnum[8]="拔"
  15. cnum[9]="玖"
  16. cnum[0]="零"

  17. cmag[0]=""
  18. cmag[1]="拾"
  19. cmag[2]="佰"
  20. cmag[3]="仟"
  21. cmag[4]="万"
  22. cmag[5]="拾"
  23. cmag[6]="百"
  24. cmag[7]="千"


  25. tempalpha="$1";
  26. ctempmag=$2;
  27. if [ $tempalpha == "00000000" ] ; then
  28. CSTR="";
  29. return 0;
  30. fi
  31. let templength="${#tempalpha}";

  32. CSTR="";
  33. for ((m=0;m<templength;m++))
  34. do
  35. tempi=${tempalpha:m:1};
  36. let tempj="$templength-$m-1";

  37. if ((( tempi == 0 )) && (( tempj ==4 ))); then
  38. CSTR=$CSTR"万";
  39. elif (( tempi == 0 )); then
  40. CSTR=$CSTR${cnum[0]};
  41. else
  42. CSTR=$CSTR${cnum[$tempi]}${cmag[$tempj]};
  43. fi

  44. done

  45. CSTR=$(echo $CSTR | sed -e 's/零零*/零/g' -e 's/零$//g' -e 's/零零零万//g');
  46. CMAG="";
  47. for ((m=0;m<ctempmag;m++))
  48. do
  49. CMAG=$CMAG"亿";
  50. done

  51. CSTR=$CSTR$CMAG;
  52. }

  53. alpha=$1;
  54. length=${#alpha};
  55. let k="$length/8";
  56. let modl="$length%8";
  57. MYSTR="";

  58. tempstr=${alpha:0:$modl};
  59. if ((modl>0)); then cconvert $tempstr $k; fi

  60. MYSTR=$MYSTR$CSTR;
  61. for ((i=0;i<k;i++))
  62. do
  63. let pos="$i*8+modl";
  64. tempstr=${alpha:$pos:8};
  65. let tempmag="$k-$i-1";
  66. cconvert $tempstr $tempmag;
  67. MYSTR=$MYSTR$CSTR;
  68. done

  69. echo $MYSTR | sed -e 's/亿零万/亿零/g' -e 's/零万/万/g' -e 's/零亿/亿/g' -e 's/零零*/零/g' -e 's/零$//g';
复制代码

[ 本帖最后由 haimming 于 2009-11-3 20:04 编辑 ]

评分

参与人数 1可用积分 +5 收起 理由
blackold + 5

查看全部评分

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
2 [报告]
发表于 2009-11-02 21:53 |只看该作者
henhaohenqiangda

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
3 [报告]
发表于 2009-11-02 21:57 |只看该作者

相当的强大!

[ 本帖最后由 blackold 于 2009-11-3 07:13 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2009-11-02 22:12 |只看该作者
网上有excel人民币大小写转换,也是输入数值,出现圆角分整等。
我们输入每项发票的钱数和内容。自动累计,自动出人民币大写。
令我们报销很方便 模板谁要???

论坛徽章:
33
ChinaUnix元老
日期:2015-02-02 08:55:39CU十四周年纪念徽章
日期:2019-08-20 08:30:3720周年集字徽章-周	
日期:2020-10-28 14:13:3020周年集字徽章-20	
日期:2020-10-28 14:04:3019周年集字徽章-CU
日期:2019-09-08 23:26:2519周年集字徽章-19
日期:2019-08-27 13:31:262016科比退役纪念章
日期:2022-04-24 14:33:24
5 [报告]
发表于 2009-11-03 02:14 |只看该作者
我在本版看过的几个:
  1. #!/usr/bin/sh
  2. if [ -f moneytmp ]
  3. then
  4. rm moneytmp
  5. fi
  6. echo "please input number"
  7. read money
  8. int=`echo $money | cut -d "." -f1`
  9. echo $money | grep "\." && dec=`echo $money | cut -d "." -f2`
  10. intlength=`echo $int | wc -c`
  11. intlength=`expr $intlength - 1`
  12. con=$intlength
  13. declength=`echo $dec | wc -c`
  14. declength=`expr $declength - 1`
  15. while [ ${i:=1} -le $intlength ]
  16. do
  17. num=`echo $int | cut -c $i`
  18. case $num in
  19. 1) echo "壹\c" >> moneytmp ;;
  20. 2) echo "贰\c" >> moneytmp ;;
  21. 3) echo "叁\c" >> moneytmp ;;
  22. 4) echo "肆\c" >> moneytmp ;;
  23. 5) echo "伍\c" >> moneytmp ;;
  24. 6) echo "陆\c" >> moneytmp ;;
  25. 7) echo "柒\c" >> moneytmp ;;
  26. 8) echo "捌\c" >> moneytmp ;;
  27. 9) echo "玖\c" >> moneytmp ;;
  28. 0)
  29. case $con in
  30. 1) echo "元\c" >> moneytmp ; i=`expr $i + 1` ; con=`expr $con - 1` ; continue ;;
  31. 5) echo "万\c" >> moneytmp ; i=`expr $i + 1` ; con=`expr $con - 1` ; continue ;;
  32. 9) echo "亿\c" >> moneytmp ; i=`expr $i + 1` ; con=`expr $con - 1` ; continue ;;
  33. *) echo "零\c" >> moneytmp ; i=`expr $i + 1` ; con=`expr $con - 1` ; continue ;;
  34. esac
  35. ;;
  36. esac
  37. case $con in
  38. 1) echo "元\c" >> moneytmp ;;
  39. 2) echo "拾\c" >> moneytmp ;;
  40. 3) echo "佰\c" >> moneytmp ;;
  41. 4) echo "仟\c" >> moneytmp ;;
  42. 5) echo "万\c" >> moneytmp ;;
  43. 6) echo "拾\c" >> moneytmp ;;
  44. 7) echo "佰\c" >> moneytmp ;;
  45. 8) echo "仟\c" >> moneytmp ;;
  46. 9) echo "亿\c" >> moneytmp ;;
  47. 10) echo "拾\c" >> moneytmp ;;
  48. 11) echo "佰\c" >> moneytmp ;;
  49. 12) echo "仟\c" >> moneytmp ;;
  50. esac
  51. i=`expr $i + 1`
  52. con=`expr $con - 1`
  53. done
  54. while [ ${j:=1} -le $declength ]
  55. do
  56. num=`echo $dec | cut -c $j`
  57. case $num in
  58. 1) echo "壹\c" >> moneytmp ;;
  59. 2) echo "贰\c" >> moneytmp ;;
  60. 3) echo "叁\c" >> moneytmp ;;
  61. 4) echo "肆\c" >> moneytmp ;;
  62. 5) echo "伍\c" >> moneytmp ;;
  63. 6) echo "陆\c" >> moneytmp ;;
  64. 7) echo "柒\c" >> moneytmp ;;
  65. 8) echo "捌\c" >> moneytmp ;;
  66. 9) echo "玖\c" >> moneytmp ;;
  67. 0) echo "零\c" >> moneytmp ;;
  68. esac
  69. case $j in
  70. 1) echo "角\c" >> moneytmp ;;
  71. 2) echo "分\c" >> moneytmp ;;
  72. esac
  73. j=`expr $j + 1`
  74. done
  75. echo >> moneytmp
  76. cat moneytmp | sed "s/零零/零/g" | sed "s/零零/零/g" | sed "s/零元/元/;s/零万/万/;s/零亿/亿/" | sed "s/亿万/亿/"
复制代码

论坛徽章:
33
ChinaUnix元老
日期:2015-02-02 08:55:39CU十四周年纪念徽章
日期:2019-08-20 08:30:3720周年集字徽章-周	
日期:2020-10-28 14:13:3020周年集字徽章-20	
日期:2020-10-28 14:04:3019周年集字徽章-CU
日期:2019-09-08 23:26:2519周年集字徽章-19
日期:2019-08-27 13:31:262016科比退役纪念章
日期:2022-04-24 14:33:24
6 [报告]
发表于 2009-11-03 02:15 |只看该作者
  1. #zh.ksh
  2. [ $# != 1 ] && echo eg:$0 1236.36 && exit
  3. printf "%.2f" $1 >/dev/null 2>&1 3>&1 || {
  4. print "非法输入,请重输!!!"; exit
  5. }
  6. Num[0]="零" Num[1]="壹" Num[2]="贰" Num[3]="叁" Num[4]="肆" Num[5]="伍"
  7. Num[6]="陆" Num[7]="柒" Num[8]="捌" Num[9]="玖"
  8. Unit[1]="分" Unit[2]="角" Unit[3]="元" Unit[4]="拾" Unit[5]="佰" Unit[6]="仟"
  9. Unit[7]="万" Unit[11]="亿"
  10. [ `echo $1 | grep "-"` ] && {
  11. NumStr=`echo $1 | sed 's/^.//'`
  12. RedFlag="(负)"
  13. } || {
  14.         NumStr=$1
  15.         RedFlag=""
  16. }
  17. i=1
  18. for TmpC in `printf "%.2f" $NumStr | nawk -F "." '{ print $1 $2 }' | sed 's/./& /g'`
  19. do
  20.         Nums[$i]=$TmpC
  21.         i=`expr $i + 1`
  22. done
  23. j=${#Nums[@]}      
  24. k=1
  25. ChnNum=""
  26. while
  27.         [ $j -eq 0 ] && break
  28.         [ $k -gt 11 ] && {
  29.                 ChnNum=${Num[${Nums[$j]}]}${Unit[`expr $k - 8 `]}$ChnNum
  30.                 j=`expr $j - 1`
  31.                 k=`expr $k + 1`
  32.                 continue
  33.         }
  34.         [ $k -gt 7 -a $k -lt 11 ] && {
  35.     ChnNum=${Num[${Nums[$j]}]}${Unit[`expr $k - 4 `]}$ChnNum
  36.     j=`expr $j - 1`
  37.     k=`expr $k + 1`
  38.     continue
  39. }
  40. ChnNum=${Num[${Nums[$j]}]}${Unit[$k]}$ChnNum
  41. do
  42.   j=`expr $j - 1`
  43.   k=`expr $k + 1`
  44. done
  45. ChnNum=`print $RedFlag$ChnNum |
  46. sed 's/零分/整/
  47.          s/零角/零/g
  48.          s/零拾/零/g
  49.          s/零佰/零/g
  50.          s/零仟/零/g
  51.          s/零整/整/g
  52.          s/角整/角/g
  53.          s/零零零零万/零/'`
  54. while
  55.   [ `print $ChnNum | grep "零零"` ] || {
  56.      ChnNum=`print $ChnNum  |
  57.                 sed 's/零元/元/
  58.                             s/零万/万/
  59.                       s/零亿/亿/
  60.                          s/^元//
  61.                          s/^零//
  62.                          s/^整$/零元&/`
  63.      break
  64. }
  65. do
  66.         ChnNum=`print $ChnNum | sed 's/零零/零/g'`
  67. done
  68. echo $ChnNum    $1
复制代码

论坛徽章:
33
ChinaUnix元老
日期:2015-02-02 08:55:39CU十四周年纪念徽章
日期:2019-08-20 08:30:3720周年集字徽章-周	
日期:2020-10-28 14:13:3020周年集字徽章-20	
日期:2020-10-28 14:04:3019周年集字徽章-CU
日期:2019-09-08 23:26:2519周年集字徽章-19
日期:2019-08-27 13:31:262016科比退役纪念章
日期:2022-04-24 14:33:24
7 [报告]
发表于 2009-11-03 02:15 |只看该作者
  1. #!/bin/sh
  2. #执行 dig2ch.sh ?????????????.??
  3. #支持最大到15位数字包括小数点
  4. numberchar()
  5. {
  6. numlist=`expr $1 + 1`
  7. c_number="零 壹 贰 叁 肆 伍 陆 柒 捌 玖"
  8. echo $c_number | awk '{print $"'$numlist'"}'
  9. return 0
  10. }

  11. rmbchar()
  12. {
  13. numlist=`expr $1 + 1`
  14. c_number="分 角 null 元 拾 佰 仟 万 拾 佰 仟 亿 拾 佰 仟"
  15. if [ $1 -eq 2 ] ; then
  16. echo ""
  17. else
  18. echo $c_number | awk '{print $"'$numlist'"}'
  19. fi
  20. return 0
  21. }

  22. money2chinese()
  23. {
  24. i=0
  25. len=`echo $1 | awk '{print length($0)}'`
  26. fundstr=$1
  27. chinese=""
  28. zerotype=0
  29. allzero=1
  30. while [ $i -lt $len ]
  31. do
  32. j=`expr $i + 1`
  33. case `echo $fundstr | awk '{print substr($0,"'$j'", 1)}'` in
  34. -) chinese="负"
  35. ;;
  36. .) if [ -z "$chinese" ]
  37. then
  38. chinese=`numberchar 0`
  39. fi
  40. if [ $zerotype -eq 1 ]
  41. then
  42. chinese=$chinese"`rmbchar 3`"
  43. zerotype=0
  44. fi
  45. ;;
  46. 0) if [ `expr $len - $i` -eq 12 ]
  47. then
  48. chinese=$chinese"`rmbchar 11`"
  49. fi
  50. if [ `expr $len - $i` -eq 8 ]
  51. then
  52. if [ $allzero -eq 0 ]
  53. then
  54. chinese=$chinese"`rmbchar 7`"
  55. fi
  56. fi
  57. zerotype=1
  58. ;;
  59. *) if [ `expr $len - $i` -lt 12 ]
  60. then
  61. allzero=0
  62. fi
  63. if [ $zerotype -eq 1 ]
  64. then
  65. chinese=$chinese"`numberchar 0`"
  66. fi
  67. num1_9=`echo $fundstr | awk '{print substr($0,"'$j'", 1)}'`
  68. chinese=$chinese"`numberchar $num1_9`"
  69. num1_9=`expr $len - $i - 1`
  70. chinese=$chinese"`rmbchar $num1_9`"
  71. zerotype=0
  72. ;;
  73. esac
  74. i=`expr $i + 1`
  75. done
  76. if [ `expr $fundstr : '.*\(..\)'` -eq "00" ]
  77. then
  78. chinese=$chinese"整"
  79. fi
  80. echo $chinese
  81. return 0
  82. }
  83. if [ -z "`expr $1 : '[0-9].*\.\([0-9].\)'`" ]
  84. then
  85. echo "bad number\n"
  86. exit 0
  87. else
  88. money2chinese $1
  89. fi
复制代码

论坛徽章:
33
ChinaUnix元老
日期:2015-02-02 08:55:39CU十四周年纪念徽章
日期:2019-08-20 08:30:3720周年集字徽章-周	
日期:2020-10-28 14:13:3020周年集字徽章-20	
日期:2020-10-28 14:04:3019周年集字徽章-CU
日期:2019-09-08 23:26:2519周年集字徽章-19
日期:2019-08-27 13:31:262016科比退役纪念章
日期:2022-04-24 14:33:24
8 [报告]
发表于 2009-11-03 02:16 |只看该作者
  1. #!/bin/ksh
  2. # Program Name : Num2Chn.sh
  3. # Programmer   : 吕永辉(仙桃市信用联社)
  4. # 首先判断输入的是否为数字
  5. printf "%.2f" $1 >/dev/null 2>&1 3>&1 || {
  6.    echo "输入非法!!!";exit
  7. }
  8. # 定义数字数组
  9. Num[0]="零" Num[1]="壹" Num[2]="贰" Num[3]="叁" Num[4]="肆" Num[5]="伍"
  10. Num[6]="陆" Num[7]="柒" Num[8]="捌" Num[9]="玖"
  11. # 定义金额单位数组
  12. Unit[1]="分" Unit[2]="角" Unit[3]="元" Unit[4]="拾" Unit[5]="佰" Unit[6]="仟"
  13. Unit[7]="万" Unit[11]="亿"
  14. # 处理负数的情况(红字)
  15. [ `echo $1 | grep "-"` ] && {
  16. NumStr=`echo $1 | sed 's/^.//'`
  17. RedFlag="(红)"
  18. } || {
  19. NumStr=$1
  20. RedFlag=""
  21. }
  22. # 初始化输入数字数组
  23. i=1
  24. for TmpC in `printf "%.2f" $NumStr | awk -F "." '{print $1$2}' | sed 's/./& /g'`
  25. do
  26.   Nums[$i]=$TmpC
  27.   i=`expr $i + 1`
  28. done
  29. j=${#Nums[@]}       # 为循环计数变量附初值为输入数字的长度
  30. k=1                 # 为循环定位变量附初值(用于确定金额单位)
  31. ChnNum=""           # 初始化大写金额字符串
  32. while
  33.   [ $j -eq 0 ] && break
  34.   [ $k -gt 11 ] && {
  35.     ChnNum=${Num[${Nums[$j]}]}${Unit[`expr $k - 8 `]}$ChnNum
  36.     j=`expr $j - 1`
  37.     k=`expr $k + 1`
  38.     continue
  39. }
  40.   [ $k -gt 7 -a $k -lt 11 ] && {
  41.     ChnNum=${Num[${Nums[$j]}]}${Unit[`expr $k - 4 `]}$ChnNum
  42.     j=`expr $j - 1`
  43.     k=`expr $k + 1`
  44.     continue
  45. }
  46.   ChnNum=${Num[${Nums[$j]}]}${Unit[$k]}$ChnNum
  47. do
  48.   j=`expr $j - 1`
  49.   k=`expr $k + 1`
  50. done
  51. ChnNum=`echo $RedFlag$ChnNum | sed 's/零分/整/' | sed 's/零角/零/g' \
  52.             | sed 's/零拾/零/g' | sed 's/零佰/零/g' | sed 's/零仟/零/g'\
  53.             | sed 's/零整/整/' | sed 's/零零零零万/零/'`
  54. # 下面的循环用于去掉字符串中连续的零
  55. while
  56.   [ `echo $ChnNum | grep "零零"` ] || {
  57.      ChnNum=`echo $ChnNum  | sed 's/零元/元/'| sed 's/零万/万/' \
  58.        | sed 's/零亿/亿/' | sed 's/^元//' | sed 's/^零//' | sed 's/^整$/零元&/`
  59.      break
  60. }
  61. do
  62.   ChnNum=`echo $ChnNum | sed 's/零零/零/g'`
  63. done
  64. echo $ChnNum
复制代码

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
9 [报告]
发表于 2009-11-03 07:08 |只看该作者

回复 #4 aleng 的帖子

就是使用函数吧?

论坛徽章:
0
10 [报告]
发表于 2009-11-03 09:08 |只看该作者

回复 #8 Shell_HAT 的帖子

大师给添了这么多版本,我还是把题目改改吧
方便大家查找

[ 本帖最后由 haimming 于 2009-11-3 09:09 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP