阿拉伯数字转中文数字脚本_2.0

阿拉伯数字转中文数字脚本_2.0。

优化版本修复上个版本的问题,可能有其他问题,欢迎指正。

#!/bin/bash
# 阿拉伯数字转换成中文数字(最大支持到9 9999 9999 9999 9999(17位)),限制阿拉伯数字必须为整数。
# 2.0优化版本

# 设置一个 num2cn 函数,阿拉伯数字转中文数字。
num2cn() {
    # 如果没有传入参数,则退出该函数而非脚本,这个错误代码。如果执行该函数之后还执行其他命令则该错误代码无法通过 $? 查询到。
    [ -z ${1} ] && echo "未输入参数,退出!" && return 1
    # 判断你输入的是否为一个整数,非整数时退出该函数。
    echo "${1}" | grep '[^0-9]' &>/dev/null && echo "你输入的不是一个整数(${1}), 退出!" && return 2
    num=${1}
    # 定义 num_cn_array 数组,0 位对应 零 ; 1 对应 一 2 对应 二 ; 以此类推。
    local num_cn_array=(零 一 二 三 四 五 六 七 八 九)
    # 定义 num_units_array 数组,赋予 个位 对应 ""(空) ; 百位 对应 百 ; 千位 对应 千 ;以此类推。
    local num_units_array=("" 十 百 千 万 十 百 千 亿 十 百 千 兆 十 百 千 京)

    # 统计输入的数字有多少位,用于下面的循环,有多少位循环多少次。
    char_length=$(expr length ${num}) ; [ ${char_length} -gt 17 ] && echo "输入的数字太大,超过17位,退出!" && return 3
    # 定义变量(a=0)用于循环取输入输入数字的第N位数字。
    local a=0

    local num_cn_temp_zero_count=0
    for ((i=${char_length};i>=1;i--))
    do
        # 循环一次变量的值加一,取数字从左边(最高位)开始第N位数字。
        let a++
        # 因为数组是从零开始的而i是从1开始的,所以变量(i)的值减一。便于后面取出第N位对应的数字单位,从最高位开始到个位("")。
        local num_units_temp=$((i - 1))
        # 取出 $num 第 $a 位值的数字赋予变量(num_temp),从最高位位开始到个位。
        local num_temp=$(echo $num | cut -c $a)
        # 判断该位置上的值是否为零,如果为零则取消该位置显示即 num_cn_temp 变量为空。
        if [ ${num_temp} -eq 0 ];then

            let num_cn_temp_zero_count++
            # 因为 0 除以任何数都等于 0 所以当 $i 等于 1 时,直接赋值 num_cn_units_judge=1。
            # 因为第5位是万位分界线,第9位是亿分界线,第13位是兆位分界线,以此类推得出“ ($i - 1)/4 ” 整除,$i的位置是大单位(万、亿、兆、京......)的分界线
            if [ ${i} -eq 1 ]; then
                num_cn_units_judge=1
            else
                let num_cn_units_judge=(${i}-1)%4
            fi

            # 判断是否$i位置是否在大单位的分界线上,如果在就把 $num_cn_temp_zero_count 变量的值初始化为 0(因为跨过大单位分界线后需要重新统计0的次数,所以 $num_cn_temp_zero_count 的最大值是 4)。
            if [ ${num_cn_units_judge} -eq 0 ]; then
                # 当 $num_cn_temp_zero_count 的值等于4 时,该大单位段都是0,可以大单位省略不写。(例如: 100000000 可以写成 一亿,而非一亿零万零)
                if [ ${num_cn_temp_zero_count} -eq 4 ]; then
                    local num_cn_temp=''
                else
                    # 如果 当 ${num_cn_temp_zero_count} 的值不等于4 时,需要将大单位前的零删除,
                    local num_cn_temp_2=$(echo "${num_cn_temp_2}" | sed "s/零$//")
                    # 然后只显示大单位。(例如:10000000 可以写成 一百万,而非 一百零万)
                    local num_cn_temp=${num_units_array[num_units_temp]}
                fi
                # 每次过大单位后 $num_cn_temp_zero_count 的值就清零。
                local num_cn_temp_zero_count=0
            else
                # 如果不在大单位分界线上, $num_cn_temp_zero_count 的值等于 1 ,且 $i 不等 1 时就直接赋予 $num_cn_temp 的值等于零。用于后面的 $num_cn_temp 的拼接。
                if [ ${num_cn_temp_zero_count} -eq 1 -a ${i} -ne 1 ]; then
                    local num_cn_temp="零"
                else
                    # 当 $num_cn_temp_zero_count 的值大于 1,就删除 $num_cn_temp 的值中结尾的零,如果结尾没有零就不会进行操作。
                    # 当 $i 等于 1 时,本次就不给 $num_cn_temp 赋值(因为中文数字中的最后一位的 零 可以不写,例如 10 可以写成 十,而非 十零。),执行下面一条命令相当于未做什么操作。
                    local num_cn_temp_2=$(echo "${num_cn_temp_2}" | sed "s/零$//")
                fi

            fi

        else
            # 判断 $num_cn_temp_zero_count 的值大于 1 时,在 $num_cn_temp 值的前面加上 零,因为  $num_cn_temp_zero_count 的值大于1 时就把 $num_cn_temp_2 的末尾的零删除了。当该字段非零时需要在它前面加上一个零。
            if [ ${num_cn_temp_zero_count} -gt 1 ];then
                # 当 $i 和 $char_length 的值都等于 2、6、10、14,且 $num_temp 等于 1 时,不输出值一,只输出单位十。(例如:10 写成 十, 而非一十。)
                if [[ "$i" =~ ^(2|6|10|14)$ && "$char_length" =~ ^(2|6|10|14)$ ]]; then
                    if [ "$i" == 2 -a "$char_length" == 2 -a "$num_temp" == 1 ]; then
                        local num_cn_temp="零"${num_units_array[num_units_temp]}
                    elif [ "$i" == 6 -a "$char_length" == 6 -a "$num_temp" == 1 ]; then
                        local num_cn_temp="零"${num_units_array[num_units_temp]}
                    elif [ "$i" == 10 -a "$char_length" == 10 -a "$num_temp" == 1 ]; then
                        local num_cn_temp="零"${num_units_array[num_units_temp]}
                    elif [ "$i" == 14 -a "$char_length" == 14 -a "$num_temp" == 1 ]; then
                        local num_cn_temp="零"${num_units_array[num_units_temp]}
                    else
                        local num_cn_temp="零"${num_cn_array[$num_temp]}${num_units_array[num_units_temp]}
                    fi  
                    
                else
                    # 把 num_cn_array 数组的第 $num_temp 位的值 和 num_units_array 数组的第 $num_units_temp 位的值 组合到一起赋予给变量(num_cn_temp)。
                    local num_cn_temp="零"${num_cn_array[$num_temp]}${num_units_array[num_units_temp]}
                fi
            else

                if [[ "$i" =~ ^(2|6|10|14)$ && "$char_length" =~ ^(2|6|10|14)$ ]]; then
                    if [ "$i" == 2 -a "$char_length" == 2 -a "$num_temp" == 1 ]; then
                        local num_cn_temp=${num_units_array[num_units_temp]}
                    elif [ "$i" == 6 -a "$char_length" == 6 -a "$num_temp" == 1 ]; then
                        local num_cn_temp=${num_units_array[num_units_temp]}
                    elif [ "$i" == 10 -a "$char_length" == 10 -a "$num_temp" == 1 ]; then
                        local num_cn_temp=${num_units_array[num_units_temp]}
                    elif [ "$i" == 12 -a "$char_length" == 12 -a "$num_temp" == 1 ]; then
                        local num_cn_temp=${num_units_array[num_units_temp]}
                    else
                        local num_cn_temp=${num_cn_array[$num_temp]}${num_units_array[num_units_temp]}
                    fi  
                    
                else
                    # 把 num_cn_array 数组的第 $num_temp 位的值 和 num_units_array 数组的第 $num_units_temp 位的值 组合到一起赋予给变量(num_cn_temp)。
                    local num_cn_temp=${num_cn_array[$num_temp]}${num_units_array[num_units_temp]}
                fi
            fi
            # 大单位段中出现非零的数值时,重置 $num_cn_temp_zero_count 的值等于零。
            local num_cn_temp_zero_count=0
        fi
        # 每循环一次,把 $num_cn_temp_2 的值和 $num_cn_temp 的值组合到一起赋予该变量 num_cn_temp_2 。 因为是从高位开始的所以 num_cn_temp_2 在前,num_cn_temp 在后。
        local num_cn_temp_2=${num_cn_temp_2}${num_cn_temp}
        unset num_cn_temp
    done
    num_cn=${num_cn_temp_2}
    echo "你输入的阿拉伯数字:${num} 对应的中文数字为: ${num_cn} 。"
}

# 测试
num2cn 99999999999999999
while true
do

    read -p "请输入整数, (如需退出输入 \"bye\" 。):" test_num
    [ "${test_num}" == "bye" ] && exit 0
    num2cn $test_num
done

注:修复上个版本的问题。

[root@10 ~]# sh shdir/test.sh
你输入的阿拉伯数字:99999999999999999 对应的中文数字为: 九京九千九百九十九兆九千九百九十九亿九千九百九十九万九千九百九十九 。
请输入整数, (如需退出输入 "bye" 。):100
你输入的阿拉伯数字:100 对应的中文数字为: 一百 。
请输入整数, (如需退出输入 "bye" 。):101
你输入的阿拉伯数字:101 对应的中文数字为: 一百零一 。
请输入整数, (如需退出输入 "bye" 。):bye
[root@10 ~]#
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容