哪个是当前的小数点分隔符?

gbo*_*ffi 31 shell posix locale floating-point

假设我有一个 POSIX shell 脚本

  1. 需要在我无法控制的不同系统/环境中运行,并且
  2. 需要从尊重语言环境设置的程序发出的字符串中删除小数点分隔符。

如何以最通用的方式检测小数点分隔符?

Ste*_*itt 46

locale

locale decimal_point
Run Code Online (Sandbox Code Playgroud)

这将使用当前区域设置输出小数点。

如果您需要千位分隔符:

locale thousands_sep
Run Code Online (Sandbox Code Playgroud)

您可以通过请求查看所有的数字关键字LC_NUMERIC类别

locale -k LC_NUMERIC
Run Code Online (Sandbox Code Playgroud)

  • @muru `printf "%'f"` 会这样做,对于支持 `%f` 的 `printf` 实现。 (3认同)
  • @muru 我所知道的唯一可以输出小数分隔符的 _builtin_ 是 `printf`,并且某些 shell(例如,`dash`)不支持国际化输出。在另一个答案中,Stéphane Chazelas 在 [评论](https://unix.stackexchange.com/questions/541342/which-is-the-current-decimal-separator#comment1003598_541355) 中解释说,POSIX 不需要它 (2认同)

Sté*_*las 6

如果这是一个zshshell 脚本,你可以$langinfozsh/langinfo模块中使用特殊的关联数组:

zmodload zsh/langinfo
radix=$langinfo[RADIXCHAR]
Run Code Online (Sandbox Code Playgroud)

(映射到标准nl_langinfo(RADIXCHAR)man nl_langinfo有关详细信息,请参阅您的系统;$langinfo[THOUSEP]对于千位分隔符)。

bash脚本中(也可以在 中工作zsh),您应该能够在不使用printf内置程序分叉单独进程的情况下获得它:

printf -v radix %.1f 1 && radix=${radix:1:1}
Run Code Online (Sandbox Code Playgroud)

要将数字从用户的语言环境格式转换为 C 语言环境格式,使用 ksh93 shell,您可以这样做:

$ locale title
German locale for Germany
$ x=1.123.456,78 ksh -c 'typeset -F x="$x"; LC_ALL=C; printf "%.23g\n" "$x"'
1123456.78
Run Code Online (Sandbox Code Playgroud)