ความไวตัวพิมพ์เล็กในวงกลมแบบเหลี่ยมยึด


10

โดยปกติทุบตีทุบตีเป็นกรณี ๆ ไป:

$ echo c*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo C*
CarePackage.md ChocRippleCake.md Clips

การใช้วงเล็บเหลี่ยมดูเหมือนจะไม่เปลี่ยนแปลงสิ่งนี้:

$ echo [c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C]*
CarePackage.md ChocRippleCake.md Clips

มันยังคงไม่เปลี่ยนถ้าใช้ยัติภังค์:

$ echo [c-c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C-C]*
CarePackage.md ChocRippleCake.md Clips

แต่ตัวอักษรจะกระจาย:

$ echo [B-C]*
CarePackage.md casefix.pike cdless chalices.py charconv.py chocolate.pike ChocRippleCake.md circum.py clip.pike Clips cpustats.pike crop.pike cwk2txt.py
$ echo [b-c]*
beehive-anthem.txt bluray2mkv.pike branch branchcleanup.pike burdayim.pike casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py

สิ่งนี้บ่งชี้ว่ายัติภังค์กำลังใช้คำสั่งโลแคล "AaBbCcDd" ดังนั้น: มีวิธีใดบ้างที่จะทำให้ glob สำหรับไฟล์ทั้งหมดที่ขึ้นต้นด้วยตัวอักษรตัวพิมพ์ใหญ่?


3
โปรดทราบด้วยว่า gotcha ที่ [AZ] ตรงกับตัวอักษรพิมพ์เล็กทุกตัวยกเว้น 'z'!
PJTraill

คำตอบ:


12

ใน bash เวอร์ชั่น 4.3 และใหม่กว่ามีตัวเลือก shopt ชื่อglobasciiranges:

อ้างอิงจากshopt builtin gnu man pages :

globasciiranges
ถ้าตั้งค่านิพจน์ช่วงที่ใช้ในนิพจน์การจับคู่รูปแบบการจับคู่รูปแบบ (ดูการจับคู่รูปแบบ) ทำตัวเหมือนในโลแคล C ดั้งเดิมเมื่อทำการเปรียบเทียบ นั่นคือลำดับการเรียงของโลแคลปัจจุบันจะไม่นำมาพิจารณาดังนั้น 'b' จะไม่เรียงระหว่าง 'A' และ 'B' และอักขระ ASCII ตัวพิมพ์ใหญ่และตัวพิมพ์เล็กจะรวมเข้าด้วยกัน

เป็นผลให้คุณสามารถ

$ shopt -s globasciiranges 
$ echo [A-Z]*

ใช้shopt -uสำหรับปิดการใช้งาน

อีกวิธีหนึ่งคือเปลี่ยนโลแคลเป็น C คุณสามารถทำได้ชั่วคราวโดยใช้ subshell:

$ ( LC_ALL=C ; printf '%s\n' [A-Z]*; )

คุณจะได้รับผลลัพธ์ที่คุณต้องการและเมื่อเชลล์ย่อยเสร็จสิ้นโลแคลของเชลล์หลักของคุณจะยังคงไม่เปลี่ยนแปลงเหมือนอย่างที่เคยเป็นมา

อีกทางเลือกหนึ่งคือแทนที่จะ[A-Z]ใช้การขยายรั้ง{A..Z}ร่วมกับnullglobตัวเลือก bash shopt

โดยการเปิดใช้งานnullglobตัวเลือกหากรูปแบบไม่ตรงกันระหว่างการขยายชื่อพา ธ สตริง null จะถูกส่งกลับแทนรูปแบบเอง
ดังนั้นสิ่งนี้จะทำงานตามที่คาดไว้:

$ shopt -s nullglob;printf '%s\n' {A..Z}*

2
สมบูรณ์แบบขอบคุณ ฉันไม่สามารถใช้[[:upper:]]เพราะฉันต้องการเพียงแค่ส่วนหนึ่งของตัวอักษร แต่ใช้งานได้
rosuav

1
@rosuav ยินดีต้อนรับ ตรวจสอบทางเลือกย่อยของเชลล์
George Vasiliou

“ ถ้าเปิดใช้งานเท่ากับเท่ากับโลแคล C” - คุณหมายถึงมันส่งผลกระทบต่อโลแคลที่ใช้สำหรับการวนรอบและไม่มีอะไรอีกหรือไม่? (ลิงก์อ้างอิงจะมีประโยชน์ - ดีที่สุดที่ฉันสามารถหาได้คือgnu.org/software/bash/manual/html_node/Pattern-Matching.htmlแต่ฉันต้องการรายการของตัวเลือกเชลล์ทั้งหมด แต่ globasciiranges ขาดหายไป จากgnu.org/software/bash/manual/html_node/ … ; นอกจากนี้คำถามunix.stackexchange.com/questions/227070/…จะจัดการกับปัญหานี้อย่างกว้างขวาง) จากเวอร์ชัน 4.3
PJTraill

@PjTrail ดูการแก้ไขของฉันพร้อมลิงค์อ้างอิงไปยังตัวเลือก shopt ทั้งหมด นอกจากนี้คุณสามารถเรียกใช้man bashใน terminal ของคุณและค้นหา (โดยใช้/) สำหรับ globasciiranges
George Vasiliou

จะไม่LC_ALL=C printf '%s\n' [A-Z]*ทำงานสำหรับการแก้ปัญหาที่สองของคุณ - โดยไม่ต้อง subshell? BTW: มันมีการพิมพ์ผิด: nullblogแต่มันมีตัวละครน้อยเกินไปสำหรับฉันที่จะแก้ไข
Joe

5

คุณสามารถเขียนตัวอักษรตัวพิมพ์ใหญ่ทั้งหมดได้เช่น:

[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*

หรือใช้สามารถใช้คลาสตัวละครที่มีชื่อ[:upper:]เพื่อเป็นตัวแทนตัวอักษรตัวพิมพ์ใหญ่ทั้งหมดในปัจจุบันของคุณlocale:

[[:upper:]]*

ตามที่คุณสังเกตเห็นในขณะที่ใช้ช่วงเช่น[B-C]ตัวพิมพ์ใหญ่และตัวพิมพ์เล็กสำหรับอักขระตัวอักษรเดียวกันจะถูกจัดวาง adjacently (ตามลำดับการเรียงของlocale)


3

การรวมอักขระ“ ไม่ได้ใช้งานง่าย” ในช่วงตัวอักษรเช่นการรวมตัวอักษรตัวพิมพ์เล็กในช่วงที่ขอบเขตเป็นตัวอักษรตัวพิมพ์ใหญ่เนื่องจากการLC_COLLATEตั้งค่าโลแคล LC_COLLATEควรระบุลำดับการเรียง แต่ทำงานได้ไม่ดี (สตริงการเรียงลำดับมีความซับซ้อนมากกว่าตำแหน่งที่สามารถทำได้) และคุณจะดีกว่าหากไม่มี ฉันแนะนำให้ลบออกLC_COLLATEจากการตั้งค่าตำแหน่งที่ตั้งของคุณ หากคุณตั้งค่ากำลังLANGหรือLANGUAGEไม่ทำและตั้งค่าได้เพียงคนที่คุณต้องการ: LC_CTYPE, ,LC_MESSAGESLC_TIME

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสถานที่ตั้งดูที่ฉันควรตั้งค่าภาษาของฉันไว้ที่ใดและมีความหมายอย่างไรในการทำเช่นนั้น และตั้งค่า LC_ * แต่ไม่ใช่ LC_ALL

LC_ALL=Cเพื่อให้ได้ผลลัพธ์ที่น่าเชื่อถือในสคริปต์โดยไม่คำนึงถึงการตั้งค่าของผู้ใช้ชุด


0

ตั้ง:

shopt -u nocaseglob

จากหน้าคนทุบตี:

>     nocaseglob
>         If  set,  bash matches filenames in a case-insensitive
>         fashion when performing pathname expansion (see Pathname
>          Expansion above).

หากคุณตั้งค่า 'globasciiranges' ฉันไม่ทราบว่าจะเกิดอะไรขึ้นกับตัวละครที่ไม่ใช่ ASCII เช่น utf-8


0

echo [cC] * ควรทำในสิ่งที่คุณต้องการเช่นเดียวกัน [A-Za-z] *

ฉันมาที่นี่เพราะการวนเวียนบนระบบของฉันเพิ่งจะหยุดตัวพิมพ์เล็กและตัวใหญ่ดังนั้นสคริปต์ของฉันจึงไม่ทำงานอีกต่อไปอย่างที่ควร :-(


ตรงกันข้ามกับสิ่งที่ฉันเห็น แต่ตรวจสอบคำตอบอื่น ๆ สำหรับคำแนะนำ
rosuav
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.