从这个答案到Format currency in Bash
,我想知道如何确定哪些字符用作数字分隔符。
printf '%.5fn' $(bc -l <<<'4*a(1)')
3.14159
LANG=de_DE printf '%.5fn' $(bc -l <<<'4*a(1)')
bash: printf: 3.14159265358979323844: invalid number
3,00000
二进制计算器bc
似乎不能正确处理区域设置…
下面提到的答案,搜索小数分隔符(或基数字符),我使用了这个:
int2amount() {
local TIMEFORMAT=%U _decsep
read _decsep < <(eval 'time true' 2>&1)
_decsep=${_decsep//[0-9]}
...
}
这个工作很好:
pi() { local TIMEFORMAT=%U _decsep;read _decsep < <(eval 'time true' 2>&1);_decsep=${_decsep//[0-9]};
local pi=$(bc -l <<<'4*a(1)')
printf '%.5fn' ${pi/./$_decsep}
}
pi
3.14159
LANG=de_DE pi
3,14159
但是千个分隔符更容易找到:
printf -v ts "%'d" 1111 ; ts=${ts//1}
没有分叉,所以系统占用空间非常小。
我可以想象在源文件的开头,像这样:
numericSeparators() {
local TIMEFORMAT=%U
read NUM_DEC_SEP < <(eval 'time true' 2>&1)
NUM_DEC_SEP=${NUM_DEC_SEP//[0-9]}
printf -v NUM_THO_SEP "%'d" 1111
NUM_THO_SEP=${NUM_THO_SEP//1}
}
numericSeparators
declare -r NUM_THO_SEP NUM_DEC_SEP
...
但我认为<(eval 'time true' 2>&1)
重的目标。我正在寻找一种更轻和/或更干净的方法来确定它们(即使是十进制和千位分隔符)。
多亏了dan的回答,我的函数会变得更简单,更快!
pi() {
local _decsep pi=$(bc -l <<<'4*a(1)')
printf -v _decsep %.1f 1
printf '%.5fn' ${pi/./${_decsep:1:1}}
}
pi
3.14159
LANG=de_DE.UTF-8 pi
3,14159
numericSeparators() {
local numtest
printf -v numtest "%'.1f" 1111
NUM_THO_SEP=${numtest:1:1}
NUM_THO_SEP=${NUM_THO_SEP/1}
NUM_DEC_SEP=${numtest: -2:1}
}
numericSeparators
for loctest in C en_US.UTF-8 de_DE.UTF-8 ;do
LANG=$loctest numericSeparators
printf ' %-12s decimal: 47%s47 thousand: 47%s47n'
"$loctest" "$NUM_DEC_SEP" "$NUM_THO_SEP"
done
C decimal: '.' thousand: ''
en_US.UTF-8 decimal: '.' thousand: ','
de_DE.UTF-8 decimal: ',' thousand: '.'
您可以获得区域设置的基数字符(小数分隔符)与:
printf -v ds '%#.1f' 1
ds=${ds//[0-9]}
和千位分组分隔符:
printf -v ts "%'d" 1111
ts=${ts//1}
某些地区(例如:C
)没有千位分隔符,此时$ts
为空。相反,如果区域设置没有定义基数字符,POSIX (printf(3)
)表示它应该默认为.
。#
标志保证它将被打印。
在绝大多数情况下,您甚至不需要知道您所处的语言环境设置来正确解码任何值,而不管您自己的语言环境设置如何。
因为你不能有任何基数的2个基点(RP),你可以使用gsub()
或类似的快速计数工具来计算,
和.
中哪个有多个副本。
-
如果两者都有,那么这可能是有问题的输入。
-
如果其中一个存在,右边的一个必须是RP
-
当只有一个且有歧义时,则考虑:
如果在该字符的右边有0个或更多的数字而不是3个数字,则不可能是千位sep
更有可能的是,数千sep的两边都有数字,但有前缘或后缘基数点并不罕见
只有4到6位数字(包括基数以下的数字,假设它仍然不明确)需要额外的上下文来正确解码。