Jaki jest obecny separator dziesiętny?


29

Powiedzmy, że mam taki skrypt powłoki POSIX

  1. musi działać na różnych systemach / środowiskach, których nie kontroluję, oraz
  2. musi usunąć separator dziesiętny z ciągu emitowanego przez program, który przestrzega ustawień regionalnych.

Jak mogę wykryć separator dziesiętny w najbardziej ogólny sposób?


Jaki rodzaj skryptu? Gdzie to działa? Zaktualizuj swoje pytanie, aby można było na nie odpowiedzieć.
X Tian

@XTian Ogólny skrypt powłoki, działający w systemie Unix / Linux. Del Celowo postawiłem pytanie w najbardziej ogólny sposób, ponieważ interesuje mnie najbardziej ogólna odpowiedź, jak wskazałem w ostatnim wierszu mojego pytania.
gboffi

1
@ StéphaneChazelas Skrypt POSIX! Szczerze mówiąc, zapomniałem, że używałem tcshw ... och, na pewno można powiedzieć, że jestem stary !!!
gboffi

1
Czy nie możesz uruchomić programu emitującego łańcuch w LC_ALL=Cśrodowisku?
Ángel

@ Ángel O tak, oczywiście, że mógłbym ...
gboffi

Odpowiedzi:


43

Zapytaj locale:

locale decimal_point

Spowoduje to wyświetlenie przecinka dziesiętnego przy użyciu bieżących ustawień regionalnych.

Jeśli potrzebujesz separatora tysięcy:

locale thousands_sep

2
Przynajmniej z localeGNU libc, locale -k LC_NUMERICaby wyświetlić wszystkie ustawienia regionalne w kategorii LC_NUMERIC.
Stéphane Chazelas

3
@Kusalananda jest częścią POSIX .
Stephen Kitt

3
@muru printf "%'f"zrobiłby to dla printfimplementacji, które obsługują %f.
Stephen Kitt

2
@muru Jedynym znanym mi wbudowanym narzędziem, które może wypisać separator dziesiętny, jest to, że printfniektóre powłoki (np. dash) nie obsługują wyjścia zinternacjonalizowanego . W innej odpowiedzi Stéphane Chazelas wyjaśnił w komentarzu , że POSIX nie wymaga tego
gboffi

1
@StephenKitt Tak to jest. Dziwne, że jeszcze tego nie spotkałem. To nie pomaga, że ​​jestem w systemie, w którym takie użycie localenie jest obsługiwane.
Kusalananda

6

Jeśli jest to zshskrypt powłoki, możesz użyć $langinfospecjalnej tablicy asocjacyjnej w zsh/langinfomodule:

zmodload zsh/langinfo
radix=$langinfo[RADIXCHAR]

(to odwzorowuje do standardu nl_langinfo(RADIXCHAR), zobacz szczegóły man nl_langinfow twoim systemie; $langinfo[THOUSEP]separator tysięcy).

W bashskrypcie (również działałby zsh) powinieneś być w stanie go uzyskać bez tworzenia osobnego procesu za pomocą printfwbudowanego:

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

Aby przekonwertować liczbę z formatu ustawień regionalnych użytkownika na format ustawień regionalnych C, za pomocą powłoki ksh93 możesz to zrobić w następujący sposób:

$ 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

Czy może być najbardziej ogólny? tmp=$(printf %.1f 0);tmp=${tmp#0};radix=${tmp%0}
gboffi

1
@ gboffi, działałoby to w niektórych internacjonalizowanych printfimplementacjach, które obsługują %f, ale nie wszystkie. %fobsługa nie jest wymagana przez POSIX. printfNa dashprzykład zawsze używa.
Stéphane Chazelas

re dashnie zinternacjonalizowany ... Właśnie okazało się, że ... tak najbardziej ogólne rozwiązanie jest uciekania się locale decimal_point, prawda?
gboffi

@ gboffi, prawdopodobnie. GNU awkmoże również interpretować liczby w bieżącym języku z trybem POSIX (choć nie obsługuje separatora tysięcy).
Stéphane Chazelas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.