Say I have a POSIX shell script that

  1. needs to run on different systems/environments that I do not control, and
  2. needs to remove the decimal separator from a string that is emitted by a program that respects the locale settings.

How can I detect the decimal separator in the most general way?

  • What sort of script ? Where is it running ? Please update your question, so that it can be answered.
    – X Tian
    Sep 12, 2019 at 9:45
  • @XTian A generic shell script, that's running on a Unix/Linux system. ֎ I deliberately posed the question in the most general way because I'm interested in the most general answer, as I specified in the last line of my question.
    – gboffi
    Sep 12, 2019 at 9:49
  • 1
    @StéphaneChazelas A POSIX script! Honest, I forgot that i used to use tcsh in ..., oh my, you definitely can say that I'm OLD!!!
    – gboffi
    Sep 12, 2019 at 11:04
  • 2
    Can't you run the string-emitted program under a LC_ALL=C environment?
    – Ángel
    Sep 12, 2019 at 22:36
  • @Ángel Oh yes, of course I could...
    – gboffi
    Sep 13, 2019 at 6:02

2 Answers 2


Ask locale:

locale decimal_point

This will output the decimal point using the current locale settings.

If you need the thousands separator:

locale thousands_sep

You can view all the numeric keywords by requesting the LC_NUMERIC category:

locale -k LC_NUMERIC
  • Is there a way to have the number directly formatted using the current locale's decimal/thousands separators?
    – muru
    Sep 12, 2019 at 10:57
  • 3
    @muru printf "%'f" would do it, for printf implementations which support %f. Sep 12, 2019 at 11:05
  • 2
    @muru The only builtin that I know of, that can output a decimal separator, is printf and some shell (e.g., dash) do not support internationalized output. In another answer Stéphane Chazelas explained, in a comment, that it's not required by POSIX
    – gboffi
    Sep 12, 2019 at 11:18

If that's a zsh shell script, you can use the $langinfo special associative array in the zsh/langinfo module:

zmodload zsh/langinfo

(that maps to the standard nl_langinfo(RADIXCHAR), see man nl_langinfo on your system for details; $langinfo[THOUSEP] for the thousand separator).

In a bash script (would also work in zsh), you should be able to get it without forking a separate process using the printf builtin:

printf -v radix %.1f 1 && radix=${radix:1:1}

To convert a number from the user's locale format to the C locale format, with the ksh93 shell, you could do it like:

$ locale title
German locale for Germany
$ x=1.123.456,78 ksh -c 'typeset -F x="$x"; LC_ALL=C; printf "%.23g\n" "$x"'
  • Most generic, could it be? tmp=$(printf %.1f 0);tmp=${tmp#0};radix=${tmp%0}
    – gboffi
    Sep 12, 2019 at 10:55
  • 1
    @gboffi, that would work in some internationalized printf implementations that support %f, but not all. %f support is not mandated by POSIX. The printf of dash for instance always uses . Sep 12, 2019 at 10:57
  • re dash not internationalized... I've just found that... so the most general solution is resorting to locale decimal_point, isn't it?
    – gboffi
    Sep 12, 2019 at 11:01
  • @gboffi, probably. GNU awk can also interpret numbers in the current locale with when in POSIX mode (doesn't handle the thousand separator though). Sep 12, 2019 at 11:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.