Đó là dấu phân cách thập phân hiện tại?


29

Nói rằng tôi có một tập lệnh shell POSIX mà

  1. cần chạy trên các hệ thống / môi trường khác nhau mà tôi không kiểm soát và
  2. cần xóa dấu tách thập phân khỏi chuỗi được phát ra bởi một chương trình tôn trọng cài đặt ngôn ngữ.

Làm cách nào để phát hiện dấu tách thập phân theo cách tổng quát nhất?


Những loại kịch bản? Nó chạy ở đâu? Vui lòng cập nhật câu hỏi của bạn, để nó có thể được trả lời.
X Tian

@XTian Một tập lệnh shell chung, đang chạy trên hệ thống Unix / Linux. Tôi cố tình đặt câu hỏi theo cách chung nhất vì tôi quan tâm đến câu trả lời chung chung nhất, như tôi đã chỉ định trong dòng cuối cùng của câu hỏi.
gboffi

1
@ StéphaneChazelas Một tập lệnh POSIX! Thành thật mà nói, tôi đã quên rằng tôi đã từng sử dụng tcshtrong ..., ồ, bạn chắc chắn có thể nói rằng tôi đang ở đây !!!
gboffi

1
Bạn không thể chạy chương trình phát ra chuỗi trong một LC_ALL=Cmôi trường?
Ángel

@ Ángel Ồ vâng, tất nhiên tôi có thể ...
gboffi

Câu trả lời:


43

Hỏi locale:

locale decimal_point

Điều này sẽ xuất ra dấu thập phân bằng cách sử dụng cài đặt ngôn ngữ hiện tại.

Nếu bạn cần dấu phân cách hàng nghìn:

locale thousands_sep

2
Và ít nhất là với localeGNU libc, locale -k LC_NUMERICđể liệt kê tất cả các cài đặt ngôn ngữ trong danh mục LC_NUMERIC.
Stéphane Chazelas

3
@Kusalananda là một phần của POSIX .
Stephen Kitt

3
@muru printf "%'f"sẽ làm điều đó, để printfthực hiện mà hỗ trợ %f.
Stephen Kitt

2
@muru Công cụ dựng sẵn duy nhất mà tôi biết, có thể tạo ra dấu tách thập phân, printfvà một số shell (ví dụ dash:) không hỗ trợ đầu ra quốc tế hóa. Trong một câu trả lời khác, Stéphane Chazelas đã giải thích, trong một bình luận , rằng POSIX không yêu cầu
gboffi

1
@StephenKitt Vậy là xong. Thật kỳ lạ khi tôi không bắt gặp nó trước đây. Không có ích gì khi tôi sử dụng hệ thống mà việc sử dụng localekhông được hỗ trợ.
Kusalananda

6

Nếu đó là zshtập lệnh shell, bạn có thể sử dụng $langinfomảng kết hợp đặc biệt trong zsh/langinfomô-đun:

zmodload zsh/langinfo
radix=$langinfo[RADIXCHAR]

(ánh xạ tới tiêu chuẩn nl_langinfo(RADIXCHAR), xem man nl_langinfotrên hệ thống của bạn để biết chi tiết; $langinfo[THOUSEP]cho dấu phân cách nghìn).

Trong một bashtập lệnh (cũng sẽ hoạt động zsh), bạn sẽ có thể lấy nó mà không cần thực hiện một quy trình riêng bằng cách sử dụng printfnội dung:

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

Để chuyển đổi một số từ định dạng miền địa phương của người dùng sang định dạng ngôn ngữ C, với vỏ ksh93, bạn có thể làm như sau:

$ 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

Chung chung nhất, có thể được? tmp=$(printf %.1f 0);tmp=${tmp#0};radix=${tmp%0}
gboffi

1
@gboffi, điều đó sẽ làm việc trong một số printftriển khai quốc tế có hỗ trợ %f, nhưng không phải tất cả. %fhỗ trợ không bắt buộc bởi POSIX. Các printfsố dashví dụ luôn luôn sử dụng.
Stéphane Chazelas

lại dashkhông quốc tế hóa ... Tôi vừa mới phát hiện ra rằng ... vì vậy giải pháp chung nhất là phải dùng đến locale decimal_point, không phải là nó?
gboffi

@gboffi, có lẽ. GNU awkcũng có thể diễn giải các số trong miền địa phương hiện tại khi ở chế độ POSIX (mặc dù không xử lý dấu phân cách nghìn).
Stéphane Chazelas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.