Yang mana pemisah desimal saat ini?


29

Katakanlah saya punya skrip shell POSIX itu

  1. perlu dijalankan pada sistem / lingkungan berbeda yang tidak saya kendalikan, dan
  2. perlu menghapus pemisah desimal dari string yang dipancarkan oleh program yang menghormati pengaturan lokal.

Bagaimana saya bisa mendeteksi pemisah desimal dengan cara yang paling umum?


Script macam apa? Di mana itu berjalan? Harap perbarui pertanyaan Anda, sehingga dapat dijawab.
X Tian

@XTian Skrip shell generik, yang berjalan pada sistem Unix / Linux. ֎ Saya sengaja mengajukan pertanyaan dengan cara yang paling umum karena saya tertarik dengan jawaban yang paling umum, seperti yang saya sebutkan di baris terakhir dari pertanyaan saya.
gboffi

1
@ StéphaneChazelas Script POSIX! Jujur, saya lupa bahwa dulu saya gunakan tcshdi ..., oh my, Anda pasti bisa mengatakan bahwa saya LAMA !!!
gboffi

1
Tidak bisakah Anda menjalankan program string-emitted di bawah LC_ALL=Clingkungan?
Ángel

@ Ángel Oh ya, tentu saja saya bisa ...
gboffi

Jawaban:


43

Tanyakan locale:

locale decimal_point

Ini akan menampilkan titik desimal menggunakan pengaturan lokal saat ini.

Jika Anda membutuhkan pemisah ribuan:

locale thousands_sep

2
Dan setidaknya dengan localedari GNU libc, locale -k LC_NUMERICuntuk mendaftar semua pengaturan lokal di kategori LC_NUMERIC.
Stéphane Chazelas

3
@ Kusalananda itu bagian dari POSIX .
Stephen Kitt

3
@muru printf "%'f"akan melakukannya, untuk printfimplementasi yang mendukung %f.
Stephen Kitt

2
@uru Satu-satunya builtin yang saya tahu, yang dapat menghasilkan pemisah desimal, adalah printfdan beberapa shell (misalnya, dash) tidak mendukung output yang diinternasionalkan. Dalam jawaban lain Stéphane Chazelas menjelaskan, dalam komentar , bahwa itu tidak diperlukan oleh POSIX
gboffi

1
@StephenKitt Begitulah. Hanya aneh bahwa saya belum pernah melihatnya sebelumnya. Tidak membantu saya menggunakan sistem yang localetidak mendukung penggunaannya.
Kusalananda

6

Jika itu zshskrip shell, Anda dapat menggunakan $langinfoarray asosiatif khusus dalam zsh/langinfomodul:

zmodload zsh/langinfo
radix=$langinfo[RADIXCHAR]

(yang memetakan ke standar nl_langinfo(RADIXCHAR), lihat man nl_langinfopada sistem Anda untuk detail; $langinfo[THOUSEP]untuk seribu pemisah).

Dalam sebuah bashskrip (juga bisa digunakan zsh), Anda harus bisa mendapatkannya tanpa memalsukan proses terpisah menggunakan printfbuiltin:

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

Untuk mengonversi angka dari format lokal pengguna ke format lokal C, dengan shell ksh93, Anda dapat melakukannya seperti:

$ 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

Paling generik, mungkinkah? tmp=$(printf %.1f 0);tmp=${tmp#0};radix=${tmp%0}
gboffi

1
@ gboffi, itu akan bekerja di beberapa printfimplementasi internasional yang mendukung %f, tetapi tidak semua. %fdukungan tidak diamanatkan oleh POSIX. The printfdari dashmisalnya selalu menggunakan.
Stéphane Chazelas

sedang dashtidak diinternasionalkan ... Saya baru saja menemukan bahwa ... jadi solusi yang paling umum adalah menggunakan locale decimal_point, bukan?
gboffi

@ gboffi, mungkin. GNU awkjuga dapat menginterpretasikan angka-angka di lokal saat ini dengan ketika dalam mode POSIX (meskipun tidak menangani pemisah ribuan).
Stéphane Chazelas
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.