ระบุลำดับการเรียงด้วย LC_COLLATE เพื่อให้ตัวพิมพ์เล็กเป็นตัวพิมพ์ใหญ่ก่อน


16

รับไฟล์:

$ cat file
1
a
C
B
2
c
3
A
b

โดยค่าเริ่มต้นsortจะ:

$ sort file
1
2
3
a
A
b
B
c
C

ด้วยLC_COLLATE=Cดังนั้นจะเรียงตัวอักษรตัวพิมพ์ใหญ่ก่อนตัวพิมพ์เล็ก:

$ LC_COLLATE=C sort file
1
2
3
A
B
C
a
b
c

เป็นไปได้ไหมที่จะเรียงลำดับเพื่อกลับลำดับของเคสนั่นคือตัวเลขตัวพิมพ์เล็กและตัวพิมพ์ใหญ่?

คำตอบ:


8

ฉันไม่รู้สถานที่ใด ๆ ที่เป็นค่าเริ่มต้นเรียงลำดับตามนั้น การแก้ปัญหาคือการสร้างสถานที่ที่กำหนดเองด้วยการเรียงลำดับที่กำหนดเอง หากใครก็ตามสี่ปีต่อมาต้องการเรียงลำดับในแบบกำหนดเองนี่คือเคล็ดลับ

โลแคลส่วนใหญ่ไม่ได้ระบุลำดับการเรียงของตัวเอง แต่คัดลอกลำดับการเรียงที่กำหนดไว้/usr/share/i18n/locales/iso14651_t1_commonเพื่อให้เป็นสิ่งที่คุณต้องการแก้ไข แทนที่จะเปลี่ยนลำดับการจัดเรียงสำหรับเกือบทุกภาษาโดยการปรับเปลี่ยนต้นฉบับiso14651_t1_commonฉันขอแนะนำให้คุณทำสำเนา รายละเอียดเกี่ยวกับวิธีการเรียงลำดับการทำงานและวิธีสร้างโลแคลที่กำหนดเองใน$HOMEไดเรกทอรีของคุณโดยไม่ต้องเข้าถึงรูทในคำตอบของคำถามที่คล้ายกันนี้

ดูวิธีการaและAเรียงลำดับตามรายการในiso14651_t1_common:

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A

bและBมีความคล้ายคลึงกัน:

<U0062> <b>;<BAS>;<MIN>;IGNORE # 233 b
<U0042> <b>;<BAS>;<CAP>;IGNORE # 550 B

เราจะเห็นว่าในครั้งแรกผ่านทั้งสองaและAมีสัญลักษณ์เรียง<a>ในขณะที่ทั้งสองbและมีสัญลักษณ์เรียงB <b>เนื่องจาก<a>ปรากฏขึ้นก่อน<b>ในiso14651_t1_common, aและAมีการเชื่อมโยงก่อนและb Bรอบที่สองไม่ได้ทำลายความสัมพันธ์เพราะตัวละครทั้งสี่มีสัญลักษณ์การเรียง<BAS>แต่ในระหว่างรอบที่สามความสัมพันธ์นั้นได้รับการแก้ไขเนื่องจากสัญลักษณ์การเรียงตัวอักษรตัวพิมพ์เล็ก<MIN>ปรากฏขึ้นที่บรรทัด 3467 ก่อนสัญลักษณ์การเรียงตัวอักษรตัวพิมพ์ใหญ่<CAP>(บรรทัด 3488) . ดังนั้นการเรียงลำดับสิ้นสุดขึ้นเป็นa, A, ,bB

การสลับสัญลักษณ์การเรียงที่หนึ่งและที่สามจะเรียงลำดับตัวอักษรเป็นตัวแรกตามตัวอักษร (ล่างและบน) จากนั้นตามด้วยสำเนียง ( <BAS>หมายถึงไม่เน้นเสียง) จากนั้นตามลำดับตัวอักษร อย่างไรก็ตามทั้งสอง<MIN>และ<CAP>มาก่อนตัวเลขดังนั้นสิ่งนี้จะมีผลที่ไม่พึงประสงค์จากการใส่ตัวเลขหลังตัวอักษร

วิธีที่ง่ายที่สุดที่จะให้หลักแรกในขณะที่ทำให้ทุกตัวอักษรตัวพิมพ์เล็กมาก่อนทุก<a>ตัวอักษรพิมพ์ใหญ่คือการบังคับตัวอักษรทั้งหมดจะผูกในช่วงแรกการเปรียบเทียบโดยการตั้งค่าพวกเขาทั้งหมดจะเท่ากับ เพื่อให้แน่ใจว่าเรียงลำดับตามตัวอักษรภายในเคสให้เปลี่ยนสัญลักษณ์การเรียงล่าสุดจากIGNOREเป็นสัญลักษณ์การเรียงแรกปัจจุบัน ทำตามรูปแบบนี้aจะกลายเป็น:

<U0061> <a>;<BAS>;<MIN>;<a> # 198 a

A จะกลายเป็น:

<U0041> <a>;<BAS>;<CAP>;<a> # 517 A

b จะกลายเป็น:

<U0062> <a>;<BAS>;<MIN>;<b> # 233 b

B จะกลายเป็น:

<U0042> <a>;<BAS>;<CAP>;<b> # 550 B

และตัวอักษรอื่น ๆ ที่เหลือ

เมื่อคุณสร้างเวอร์ชันที่กำหนดเองiso14651_t1_commonแล้วให้ทำตามคำแนะนำในคำตอบที่ลิงก์ด้านบนเพื่อรวบรวมสถานที่ที่กำหนดเองของคุณ


6

การตั้งค่าLC_COLLATE=Cไม่เพียงพอสำหรับการจัดเรียงตัวพิมพ์ใหญ่ก่อนตัวพิมพ์เล็ก LC_ALL=Cคุณอาจจะต้องตั้ง

สิ่งนั้นจะคำนึงถึงตัวละครที่ไม่ใช่ตัวอักษรและตัวเลขที่ไม่สามารถพิมพ์ได้ แต่ถ้าคุณไม่ต้องการให้มีตัวเลือก-dและ-i(อธิบายไว้man sort) จะปิดตัวเอง

มันอาจจะล้มเหลวอย่างมากกับอินพุตหลายไบต์เช่น UTF-8 ที่มีอักขระที่ไม่ใช่ ASCII

เพื่อให้ได้ตัวพิมพ์เล็ก (ตามลำดับ) ก่อนที่จะเป็นตัวพิมพ์ใหญ่ (ตามลำดับ) วิธีที่ดีที่สุดที่ฉันคิดได้ว่าไม่เกี่ยวข้องกับการเขียนโปรแกรมภาษาเต็มรูปแบบคือการย้อนกลับกรณีของตัวอักษรทั้งหมดก่อนการเรียงลำดับและย้อนกลับ ภายหลัง

tr 'a-zA-Z' 'A-Za-z' < file | LC_ALL=C sort | tr 'a-zA-Z' 'A-Za-z'

2

ฉันไม่มีความเชี่ยวชาญ แต่ฉันไม่เคยเห็นสถานที่ที่กำหนดการเปรียบเทียบเช่นนี้ AFAIK การเปรียบเทียบนี้เป็นเพียงใน C ที่มันจะขึ้นอยู่กับค่า ASCII (โดยปกติฉันจะแก้ปัญหานี้ด้วยสคริปต์)

อย่างไรก็ตามฉันไม่เคยทำสิ่งนี้มาก่อน แต่คุณอาจต้องการดูlocaledef (1)และlocale (5) manpages เพื่อทำความเข้าใจเกี่ยวกับวิธีการกำหนดโลแคลและในที่สุดจะกำหนดค่าของคุณเอง

นอกจากนี้อย่าลืมว่าหากมีการกำกับใด ๆ หรือตัวละครพิเศษสถานที่ C จะไม่ปฏิบัติต่อพวกเขาตามที่คุณอาจต้องการ ยกตัวอย่างเช่นมันจะไม่ใส่áที่อยู่ใกล้aหรืออยู่ใกล้กับŁ Lในกรณีดังกล่าวภาษาท้องถิ่นของภาษาน่าจะเป็นจุดเริ่มต้นที่ดีกว่า


0

ฉันเชื่อว่าคำตอบคือไม่ต้องเปลี่ยน LC_COLLATE (หมายถึงการปล่อยให้ฟังก์ชันเป็นพฤติกรรมเริ่มต้น):

ไฟล์ sort -f

สิ่งนี้ทำงานบน Linux; โปรดดูที่ส่วนช่วยเหลือของคุณสำหรับคำสั่งในกรณีที่คุณใช้ระบบปฏิบัติการ Unix และใช้งานรุ่นอื่น -f หมายถึงกรณีที่ไม่สนใจ

ขอบคุณสำหรับการแก้ไขอย่างรวดเร็ว (& แปลก) ที่ค่อนข้างจะแก้ไขและแก้ไขไวยากรณ์ที่วางผิดที่ Stephen Rauch


-1
LC_COLLATE="en_US.UTF-8" sort file

สิ่งนี้ไม่ได้เรียงตัวพิมพ์เล็กก่อนตัวพิมพ์ใหญ่หรือไม่ ideone.com/Gtyg4Z
iiSeymour

อืมในกรณีของฉันมันใช้ตัวอย่างของคุณ
unxnut

4
@unxnut สิ่งนี้ไม่ถูกต้อง โดยไม่ต้องอัฒภาคคำสั่งจะตั้งสภาพแวดล้อมสำหรับแต่ด้วยอัฒภาคตัวแปรอยู่ภายในเปลือกและไม่ส่งผลกระทบต่อการทำงานของsort sortอัฒภาคสามารถถูกเก็บไว้ได้เช่นเดียวกับถ้าตัวแปรถูกเอ็กซ์พอร์ตเช่นกัน แต่นั่นจะมีผลกับคำสั่งอื่นเช่นกัน
Anders Sjöqvist
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.