阿拉伯数字转中文数字脚本_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 ~]#