Який поточний десятковий роздільник?


29

Скажіть, у мене є сценарій оболонки POSIX, що

  1. потрібно працювати в різних системах / середовищах, які я не контролюю, і
  2. потрібно видалити десятковий роздільник з рядка, який випромінюється програмою, яка поважає параметри локалі.

Як я можу виявити десятковий роздільник найбільш загальним способом?


Що за сценарій? Куди воно біжить? Оновіть своє запитання, щоб відповісти на нього.
X Тянь

@XTian Загальний сценарій оболонки, який працює в системі Unix / Linux. ֎ Я навмисно ставив це питання найзагальнішим чином, бо мене цікавить найзагальніша відповідь, як я вказав в останньому рядку мого запитання.
gboffi

1
@ StéphaneChazelas Сценарій POSIX! Чесно tcshкажучи , я забув, що я використовував у ..., о, мій, ви точно можете сказати, що я СТАРИЙ !!!
gboffi

1
Ви не можете запустити рядкову програму в LC_ALL=Cоточенні?
Ángel

@ Ángel О так, звичайно, я міг би ...
gboffi

Відповіді:


43

Запитайте locale:

locale decimal_point

Це виведе десяткову точку, використовуючи поточні параметри локалі.

Якщо вам потрібен роздільник тисяч:

locale thousands_sep

2
І, принаймні, з localeGNU libc, locale -k LC_NUMERICщоб перелічити всі параметри локалі в категорії LC_NUMERIC.
Стефан Шазелас

3
@Kusalananda - це частина POSIX .
Стівен Кітт

3
@muru зробив printf "%'f"би це для printfреалізацій, які підтримують %f.
Стівен Кітт

2
@muru Єдиний мені відомий вбудований модуль , який може вивести десятковий роздільник, - це те, що printfдеякі оболонки (наприклад, dash) не підтримують інтернаціоналізований вихід. В іншій відповіді Стефан Шазелас в коментарі пояснив, що POSIX цього не вимагає
gboffi

1
@StephenKitt Так і є. Дивно, що я раніше не стикався з цим. Це не допомагає, що я перебуваю в системі, де це використання localeне підтримується.
Kusalananda

6

Якщо це zshсценарій оболонки, ви можете використовувати $langinfoспеціальний асоціативний масив у zsh/langinfoмодулі:

zmodload zsh/langinfo
radix=$langinfo[RADIXCHAR]

(що відповідає стандарту nl_langinfo(RADIXCHAR); докладні відомості див. man nl_langinfoу вашій системі; $langinfo[THOUSEP]для роздільника тисяч).

У bashсценарії (також працює в zsh) ви повинні отримати його без форсування окремого процесу за допомогою printfвбудованого:

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

Щоб перетворити число з локального формату користувача у формат локалізації C, використовуючи оболонку ksh93, ви можете це зробити так:

$ 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

Найбільш загальне, це могло бути? tmp=$(printf %.1f 0);tmp=${tmp#0};radix=${tmp%0}
gboffi

1
@gboffi, це може працювати в деяких інтернаціоналізованих printfреалізаціях, які підтримують %f, але не у всіх. %fпідтримка не заборонена POSIX. printfЗ dash, наприклад , завжди використовує.
Stéphane Chazelas

Ви dashне інтернаціоналізовані ... Я щойно виявив, що ... тож до найбільш загального рішення вдаються locale decimal_point, чи не так?
gboffi

@gboffi, певно. GNU awkтакож може інтерпретувати цифри в поточному мові з тим, що перебуває в режимі POSIX (не працює з роздільником тисяч).
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.