การพิจารณาตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ในเชลล์สคริปต์


10

พิจารณาสคริปต์ Bash นี้:

#!/bin/bash
echo Enter any character
read char
case $char in
    [a-z]) echo Lower case letter
            ;;
    [A-Z]) echo Upper case letter
            ;;
    [0-9]) echo Number
            ;;
    ?) echo Special char
            ;;
    *) echo You entered more than one character 
            ;;
esac

หากฉันป้อน 'a' ผลลัพธ์จะเป็นตัวอักษรพิมพ์เล็กและจะเหมือนกันสำหรับ 'A' ... ฉันจะเอาชนะสิ่งนี้ได้อย่างไร


เมื่อคุณโพสต์สคริปต์ให้แน่ใจว่าคุณใช้รูปแบบรหัสเพื่อให้ช่องว่าง นอกจากนี้คำถามที่แท้จริงคืออะไร? ฉันไม่แน่ใจว่าคุณหมายถึงอะไร ...
AJefferiss

2
@ ตามธรรมเนียมไม่จำเป็น echo สามารถจัดการกับคำที่สงวนไว้echo if case then doได้
terdon

สำหรับปัญหาที่คล้ายกัน แต่ต้องรับมือกับการเรียงโปรดดูaskubuntu.com/questions/597924/…
Joe

คำตอบ:


20
#!/bin/bash
echo 'enter any character'
read char
case $char in
[[:lower:]]) echo 'lower case letter'
    ;;
[[:upper:]]) echo 'upper case letter'
    ;;
[0-9]) echo 'number'
    ;;
?) echo 'special char'
    ;;
*) echo 'u entered more than one char' 
    ;;
esac  

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการแสดงออกปกติกรณีที่ต่ำกว่าของ[az]และการแสดงออกปกติกรณีเล็ก ๆ ของ[AZ]ในทุบตีดูทำไมคำสั่งกรณีที่ไม่ได้เป็นกรณี ๆ ไปเมื่อ nocasematch ถูกปิด? .


6
ต่อจากนี้แทนของคุณสามารถใช้[0-9] [[:digit:]]คุณสามารถหาตัวอย่างอื่น ๆ ในman grepหรือ Google เรียนอักขระ POSIX
Paddy Landau

21

ปัญหาคือว่าช่วงตัวละคร[a-z]จริงรวมถึงตัวอักษรตัวพิมพ์ใหญ่ นี่คือคำอธิบายในคู่มือทุบตี :

ภายในนิพจน์วงเล็บเหลี่ยมนิพจน์ช่วงประกอบด้วยอักขระสองตัวคั่นด้วยเครื่องหมายยัติภังค์ มันตรงกับตัวละครเดี่ยวใด ๆ ที่เรียงลำดับระหว่างตัวละครทั้งสองรวม ในโลแคล C เริ่มต้นลำดับการเรียงคือลำดับอักขระท้องถิ่น ตัวอย่างเช่น '[ad]' เทียบเท่ากับ '[abcd]' ในตำแหน่งที่ตั้งอื่นลำดับการเรียงจะไม่ถูกระบุและ '[ad]' อาจเทียบเท่ากับ '[abcd]' หรือ '[aBbCcDd]'หรืออาจไม่ตรงกับอักขระใด ๆ หรือชุดอักขระที่ การแข่งขันอาจจะผิดปกติ หากต้องการรับการตีความดั้งเดิมของนิพจน์วงเล็บเหลี่ยมคุณสามารถใช้โลแคล 'C' ได้โดยตั้งค่าตัวแปรสภาพแวดล้อม LC_ALL ให้เป็นค่า 'C'

เพื่อแสดง:

$ case B in [a-c]) echo YES;;  *) echo NO;; esac
YES
$ LC_ALL=C; case B in [a-c]) echo YES;; *) echo NO;; esac
NO

ดังนั้นสิ่งที่เกิดขึ้นก็คือว่าในสถานที่ของคุณ (ซึ่งไม่C) เป็นจริง[a-c] [aAbBcC]นั่นเป็นเหตุผลที่คุณควรใช้คลาสอักขระ POSIX ตามที่แนะนำโดย @karel แทน


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