ตัวแยกทศนิยมปัจจุบันคืออะไร


29

บอกว่าฉันมีสคริปต์เชลล์ POSIX ที่

  1. ต้องทำงานในระบบ / สภาพแวดล้อมที่แตกต่างกันซึ่งฉันไม่ได้ควบคุมและ
  2. จำเป็นต้องลบตัวแยกทศนิยมออกจากสตริงที่ปล่อยโดยโปรแกรมที่เคารพการตั้งค่าภาษา

ฉันจะตรวจจับตัวแยกทศนิยมด้วยวิธีทั่วไปได้อย่างไร


สคริปต์ประเภทใด มันทำงานที่ไหน โปรดอัปเดตคำถามของคุณเพื่อให้สามารถตอบได้
X Tian

@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
และอย่างน้อยกับlocaleจาก GNU libc, locale -k LC_NUMERICไปยังรายการการตั้งค่าสถานที่เกิดเหตุในหมวดหมู่ LC_NUMERIC
Stéphane Chazelas

3
@Kusalananda มันเป็นส่วนหนึ่งของPOSIX
Stephen Kitt

3
@muru printf "%'f"จะทำสำหรับการใช้งานที่สนับสนุนprintf %f
Stephen Kitt

2
@muru เท่านั้นbuiltinว่าฉันรู้ว่าการส่งออกสามารถคั่นทศนิยมเป็นprintfและเปลือกบาง (เช่นdash) ไม่รองรับการส่งออกสากล ในคำตอบอื่นStéphane Chazelas อธิบายในความคิดเห็นว่า 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) คุณควรจะได้รับโดยไม่ต้องแยกกระบวนการโดยใช้printfbuiltin:

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 (ไม่ได้จัดการตัวคั่นหลักพัน)
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.