==
ผู้ประกอบการจะใช้ในการเปรียบเทียบสองสายในสคริปต์เปลือก อย่างไรก็ตามฉันต้องการเปรียบเทียบสองสตริงโดยไม่สนใจขนาดตัวพิมพ์ทำอย่างไร? มีคำสั่งมาตรฐานสำหรับสิ่งนี้หรือไม่?
==
ผู้ประกอบการจะใช้ในการเปรียบเทียบสองสายในสคริปต์เปลือก อย่างไรก็ตามฉันต้องการเปรียบเทียบสองสตริงโดยไม่สนใจขนาดตัวพิมพ์ทำอย่างไร? มีคำสั่งมาตรฐานสำหรับสิ่งนี้หรือไม่?
คำตอบ:
ถ้าคุณทุบตี
str1="MATCH"
str2="match"
shopt -s nocasematch
case "$str1" in
$str2 ) echo "match";;
*) echo "no match";;
esac
มิฉะนั้นคุณควรบอกเราว่าคุณใช้เชลล์อะไร
ทางเลือกโดยใช้ awk
str1="MATCH"
str2="match"
awk -vs1="$str1" -vs2="$str2" 'BEGIN {
if ( tolower(s1) == tolower(s2) ){
print "match"
}
}'
==
ใช้เพื่อเปรียบเทียบสองสตริง แต่การตอบกลับแสดงการเปรียบเทียบแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่โดยใช้case
คำสั่ง ทำให้อุ่นใจที่shopt
โซลูชั่นนี้ยังช่วยให้สามารถใช้กรณีตายของ==
, =~
และผู้ประกอบการเปรียบเทียบสตริงอื่น ๆ
shopt -u nocasematch
หลังจากการเปรียบเทียบเสร็จสิ้นเพื่อเปลี่ยนกลับเป็นค่าเริ่มต้นของ bash
nocasematch
ตั้งค่า คว้ามันSHELLNOCASEMATCH=`shopt -p nocasematch`
แล้วเปลี่ยนด้วยshopt -s nocasematch
และเมื่อเสร็จแล้วให้คืนค่าด้วย$SHELLNOCASEMATCH
SHELLNOCASEMATCH=$(shopt -p nocasematch; true)
เพราะshopt -p
จะออกจากรหัส 1 หากไม่ได้ตั้งค่าตัวเลือกและสิ่งนี้อาจทำให้สคริปต์ยกเลิกหากset -e
มีผล
ใน Bash คุณสามารถใช้การขยายพารามิเตอร์เพื่อแก้ไขสตริงเป็นตัวพิมพ์เล็ก / ตัวพิมพ์ใหญ่ทั้งหมด:
var1=TesT
var2=tEst
echo ${var1,,} ${var2,,}
echo ${var1^^} ${var2^^}
echo
คำสั่งแรกส่งผลให้:-bash: ${var1,,}: bad substitution
shopt -s nocasematch
จะมีการนำไปใช้อย่างไร แต่โดยปกติแล้วโซลูชัน "ระดับภาษา" นั้นจะจัดการได้อย่างถูกต้อง
คำตอบทั้งหมดเหล่านี้ไม่สนใจวิธีที่ง่ายและรวดเร็วที่สุดในการทำเช่นนี้ (ตราบใดที่คุณมี Bash 4):
if [ "${var1,,}" = "${var2,,}" ]; then
echo ":)"
fi
สิ่งที่คุณทำคือการแปลงทั้งสองสตริงเป็นตัวพิมพ์เล็กและเปรียบเทียบผลลัพธ์
บันทึกสถานะของ nocasematch (ในกรณีที่ฟังก์ชั่นอื่น ๆ นั้นขึ้นอยู่กับการปิดการใช้งาน):
local orig_nocasematch=$(shopt -p nocasematch)
shopt -s nocasematch
[[ "foo" == "Foo" ]] && echo "match" || echo "notmatch"
$orig_nocasematch
หมายเหตุ: ใช้เฉพาะในlocal
กรณีที่อยู่ภายในฟังก์ชั่น
case
ข้อความ (รวมถึงคำตอบของ ghostdog) จะทำให้การคลานผิวของฉันอยู่เสมอ
วิธีหนึ่งคือการแปลงสตริงทั้งสองเป็นบนหรือล่าง:
test $(echo "string" | /bin/tr '[:upper:]' '[:lower:]') = $(echo "String" | /bin/tr '[:upper:]' '[:lower:]') && echo same || echo different
อีกวิธีหนึ่งคือใช้ grep:
echo "string" | grep -qi '^String$' && echo same || echo different
tr
วิธีนี้ในแอพพลิเคชั่นที่ใช้งานนักเทียบท่าขึ้นอยู่กับอัลไพน์ (ซึ่งมีให้sh
ผ่านbusybox
) ขอบคุณ.
สำหรับ korn เชลล์ฉันใช้คำสั่งในตัว typeset (-l สำหรับตัวพิมพ์เล็กและ -u สำหรับตัวพิมพ์ใหญ่)
var=True
typeset -l var
if [[ $var == "true" ]]; then
print "match"
fi
ง่ายมากถ้าคุณ fgrep ทำการเปรียบเทียบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่:
str1="MATCH"
str2="match"
if [[ $(fgrep -ix $str1 <<< $str2) ]]; then
echo "case-insensitive match";
fi
นี่คือทางออกของฉันโดยใช้ tr:
var1=match
var2=MATCH
var1=`echo $var1 | tr '[A-Z]' '[a-z]'`
var2=`echo $var2 | tr '[A-Z]' '[a-z]'`
if [ "$var1" = "$var2" ] ; then
echo "MATCH"
fi
grep
มีการ-i
ตั้งค่าสถานะซึ่งหมายถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ดังนั้นขอให้มันบอกคุณว่า var2 อยู่ใน var1
var1=match
var2=MATCH
if echo $var1 | grep -i "^${var2}$" > /dev/null ; then
echo "MATCH"
fi
สำหรับzsh
ไวยากรณ์แตกต่างกันเล็กน้อย แต่ก็ยังสั้นกว่าคำตอบส่วนใหญ่ที่นี่:
> str1='mAtCh'
> str2='MaTcH'
> [[ "$str1:u" = "$str2:u" ]] && echo 'Strings Match!'
Strings Match!
>
สิ่งนี้จะแปลงทั้งสองสตริงเป็นตัวพิมพ์ใหญ่ก่อนการเปรียบเทียบ
อีกวิธีหนึ่งที่ใช้ประโยชน์จาก zsh globbing flags
ซึ่งช่วยให้เราสามารถใช้การจับคู่แบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ได้โดยตรงโดยใช้i
ธง glob:
setopt extendedglob
[[ $str1 = (#i)$str2 ]] && echo "Match success"
[[ $str1 = (#i)match ]] && echo "Match success"
shopt -s nocaseglob
ฉันเจอบล็อก / กวดวิชาที่ยอดเยี่ยมนี้ไม่ว่าจะเกี่ยวกับรูปแบบตัวพิมพ์เล็กหรือใหญ่ สามวิธีต่อไปนี้อธิบายด้วยรายละเอียดพร้อมตัวอย่าง:
1.แปลงรูปแบบเป็นตัวพิมพ์เล็กโดยใช้คำสั่งtr
opt=$( tr '[:upper:]' '[:lower:]' <<<"$1" )
case $opt in
sql)
echo "Running mysql backup using mysqldump tool..."
;;
sync)
echo "Running backup using rsync tool..."
;;
tar)
echo "Running tape backup using tar tool..."
;;
*)
echo "Other options"
;;
esac
2.ใช้ regex พร้อมรูปแบบตัวพิมพ์
opt=$1
case $opt in
[Ss][Qq][Ll])
echo "Running mysql backup using mysqldump tool..."
;;
[Ss][Yy][Nn][Cc])
echo "Running backup using rsync tool..."
;;
[Tt][Aa][Rr])
echo "Running tape backup using tar tool..."
;;
*)
echo "Other option"
;;
esac
3.เปิดnocasematch
opt=$1
shopt -s nocasematch
case $opt in
sql)
echo "Running mysql backup using mysqldump tool..."
;;
sync)
echo "Running backup using rsync tool..."
;;
tar)
echo "Running tape backup using tar tool..."
;;
*)
echo "Other option"
;;
esac
shopt -u nocasematch
if
คำสั่งshopt
วิธีการนี้กำหนดให้คุณใช้[[ ]]
รูปแบบวงเล็บคู่แบบมีเงื่อนไขแทน[ ]
รูปแบบวงเล็บปีกกาเดี่ยว ดูเพิ่มเติม: gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html