ฉันจะเปรียบเทียบตัวแปรกับสตริงได้อย่างไร (และทำบางสิ่งถ้าจับคู่กัน)
ฉันจะเปรียบเทียบตัวแปรกับสตริงได้อย่างไร (และทำบางสิ่งถ้าจับคู่กัน)
คำตอบ:
if [ "$x" = "valid" ]; then
echo "x has the value 'valid'"
fi
หากคุณต้องการที่จะทำบางสิ่งบางอย่างเมื่อพวกเขาไม่ตรงกับแทนที่ด้วย= !=คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการทำงานของสตริงและการดำเนินการทางคณิตศาสตร์ได้ในเอกสารที่เกี่ยวข้อง
$x?คุณต้องการเครื่องหมายคำพูดล้อมรอบ$xเพราะถ้ามันว่างเปล่าสคริปต์ Bash ของคุณจะพบข้อผิดพลาดทางไวยากรณ์ดังที่แสดงด้านล่าง:
if [ = "valid" ]; then
==ตัวดำเนินการที่ไม่ได้มาตรฐานโปรดทราบว่าทุบตีอนุญาต==ที่จะใช้เพื่อความเท่าเทียมกันด้วย[แต่ตอนนี้ไม่ได้มาตรฐาน
ใช้กรณีแรกที่มีเครื่องหมายคำพูดล้อมรอบ$xเป็นตัวเลือก:
if [[ "$x" == "valid" ]]; then
หรือใช้กรณีที่สอง:
if [ "$x" = "valid" ]; then
[ "$1" == "on" ]ผมได้รับข้อผิดพลาดเดียวกันเมื่อใช้ การเปลี่ยนสิ่งนี้เป็น ["$ 1" = "เปิด"] แก้ปัญหาได้
=และไม่สอง
[ $x -eq "valid" ]ได้ -eqเป็นตัวดำเนินการเปรียบเทียบสำหรับจำนวนเต็มไม่ใช่สตริง
["x$yes" == "xyes"]ที่นำหน้าทั้งตัวแปรและสตริงตามตัวอักษรด้วยx? นั่นเป็นสิ่งที่ระลึกถึงครั้งเก่าหรือจำเป็นจริงๆในบางสถานการณ์?
หรือถ้าคุณไม่ต้องการประโยคอื่น:
[ "$x" == "valid" ] && echo "x has the value 'valid'"
echoจะทำได้
[ "$X" == "valid" ] || ( echo invalid && false ) && echo "valid" ไม่มีปัญหาการใช้งาน
{ echo invalid && false; }นั้นมีประสิทธิภาพมากกว่า( echo invalid && false )เพราะหลีกเลี่ยงการจ่ายเงินสำหรับ subshell ที่ไม่จำเป็น
a="abc"
b="def"
# Equality Comparison
if [ "$a" == "$b" ]; then
echo "Strings match"
else
echo "Strings don't match"
fi
# Lexicographic (greater than, less than) comparison.
if [ "$a" \< "$b" ]; then
echo "$a is lexicographically smaller then $b"
elif [ "$a" \> "$b" ]; then
echo "$b is lexicographically smaller than $a"
else
echo "Strings are equal"
fi
หมายเหตุ:
ifและ[และ]มีความสำคัญ>และ<เป็นตัวดำเนินการเปลี่ยนเส้นทางดังนั้นควรหลีกเลี่ยง\>และ\<ใช้สตริงตามลำดับ$aจริงแล้ว" "มันล้อมรอบมันเป็นส่วนหนึ่งของค่าตัวอักษรสตริงดังนั้นฉันจึงต้องใช้อักขระตัวหนี$bเพื่อเปรียบเทียบค่า ฉันสามารถค้นหาสิ่งนี้ได้หลังจากทำงานbash -x ./script.shแฟล็ก -x ช่วยให้คุณเห็นคุณค่าของการดำเนินการแต่ละครั้งและช่วยในการดีบัก
ในการเปรียบเทียบสตริงกับ wildcard ให้ใช้
if [[ "$stringA" == *$stringB* ]]; then
# Do something here
else
# Do Something here
fi
"รอบ ๆ สัญลักษณ์แทน (btw: +1 สำหรับสัญลักษณ์ตัวแทน!)
$stringB จะต้องถูกยกมา if [[ $stringA = *"$stringB"* ]]; then(และบังเอิญทางด้านซ้ายมือไม่จำเป็นที่จะยกมา):
ฉันไม่เห็นด้วยกับหนึ่งในความคิดเห็นในจุดเดียว:
[ "$x" == "valid" ] && echo "valid" || echo "invalid"
มันเป็นเพียงดูเหมือนว่าหนึ่งถึงอืมไม่ได้ฝึกหัด ...
มันใช้รูปแบบทั่วไปเป็นภาษาในทาง;
และหลังจากที่คุณเรียนภาษา
มันคือการแสดงออกทางตรรกะที่เรียบง่ายด้วยส่วนพิเศษหนึ่ง: การประเมินผลที่ขี้เกียจของผู้ประกอบการตรรกะ
[ "$x" == "valid" ] && echo "valid" || echo "invalid"
แต่ละส่วนเป็นการแสดงออกเชิงตรรกะ ครั้งแรกอาจเป็นจริงหรือเท็จอีกสองคนเป็นจริงเสมอ
(
[ "$x" == "valid" ]
&&
echo "valid"
)
||
echo "invalid"
ตอนนี้เมื่อมีการประเมินผลการตรวจสอบครั้งแรก หากเป็นเท็จมากกว่าตัวถูกดำเนินการที่สองของตรรกะและ &&หลังจากนั้นจะไม่เกี่ยวข้อง คนแรกไม่เป็นความจริงดังนั้นจึงไม่สามารถเป็นคนแรกและคนที่สองได้จริง
ทีนี้ในกรณีนี้คือด้านแรกของตรรกะ หรือ ||เท็จ แต่มันอาจเป็นจริงถ้าอีกด้านหนึ่ง - ส่วนที่สาม - เป็นจริง
ดังนั้นส่วนที่สามจะถูกประเมิน - ส่วนใหญ่เขียนข้อความเป็นผลข้างเคียง (มันมีผล0จริงซึ่งเราไม่ได้ใช้ที่นี่)
อีกกรณีคล้ายกัน แต่ง่ายกว่า - และ - ฉันสัญญา! ง่ายต่อการอ่าน!
(ฉันไม่ได้มี แต่ฉันคิดว่าการเป็นทหารผ่านศึก UNIX ที่มีเคราสีเทาช่วยได้มากในเรื่องนี้)
... && ... || ...มักจะขมวดคิ้ว (ขออภัย greybeard Unix เก๋าคุณได้รับไม่ถูกต้องสำหรับทุกเวลานี้) if ... then ... else ...เป็นมันไม่เทียบเท่ากับความหมาย ไม่ต้องกังวลนี้เป็นหลุมพรางที่พบบ่อย
... && ... || ...เป็นรูปแบบที่ถูกต้องอย่างสมบูรณ์และสำนวนทุบตีทั่วไป การใช้มันจะกำหนดความรู้ก่อนหน้า (ซึ่งอาจเป็นเรื่องดีที่จะทราบถ้ามีผู้เริ่มต้นในผู้ชม) แต่ OP มีผมเพื่อพิสูจน์ว่าพวกเขารู้วิธีที่จะหลีกเลี่ยงครอบคลุมท่อระบายน้ำเปิด
คุณยังสามารถใช้การใช้เคส / esac
case "$string" in
"$pattern" ) echo "found";;
esac
| คำสั่งเทียบเท่ากับในงบ คุณสามารถโต้แย้งว่ามันใช้งานได้กับรายการรูปแบบที่แต่ละรายการมีการประกาศของตัวเองว่าจะทำอย่างไรถ้าคุณมาจาก Python ไม่ชอบแต่ ใช้เป็นคำสั่งสุดท้ายของคุณหากคุณต้องการเงื่อนไข มันกลับมาเมื่อเจอกันครั้งแรก )inthenifsubstring in stringfor item in list*else
สคริปต์ต่อไปนี้อ่านจากไฟล์ชื่อ "testonthis" ทีละบรรทัดแล้วเปรียบเทียบแต่ละบรรทัดด้วยสตริงแบบง่ายสตริงที่มีอักขระพิเศษและนิพจน์ทั่วไป หากไม่ตรงกันสคริปต์จะพิมพ์บรรทัดมิฉะนั้นจะไม่
ช่องว่างใน Bash นั้นสำคัญมาก ดังนั้นสิ่งต่อไปนี้จะได้ผล:
[ "$LINE" != "table_name" ]
แต่สิ่งต่อไปนี้จะไม่:
["$LINE" != "table_name"]
ดังนั้นโปรดใช้ตามที่เป็น:
cat testonthis | while read LINE
do
if [ "$LINE" != "table_name" ] && [ "$LINE" != "--------------------------------" ] && [[ "$LINE" =~ [^[:space:]] ]] && [[ "$LINE" != SQL* ]]; then
echo $LINE
fi
done
bashแต่[เป็นเพราะจริง ๆ แล้วเป็นเลขฐานสองภายนอก (เช่นเดียวกับที่which [ให้ผลเช่นนี้/usr/bin/[)
ฉันอาจจะใช้การแข่งขัน regexp ถ้าอินพุตมีรายการที่ถูกต้องเพียงไม่กี่ เช่นเฉพาะ "เริ่มต้น" และ "หยุด" เป็นการกระทำที่ถูกต้อง
if [[ "${ACTION,,}" =~ ^(start|stop)$ ]]; then
echo "valid action"
fi
โปรดทราบว่าฉันพิมพ์ตัวพิมพ์เล็ก$ACTIONโดยใช้เครื่องหมายจุลภาคสองตัว นอกจากนี้โปรดทราบว่าวิธีนี้จะไม่สามารถใช้ได้กับเวอร์ชันทุบตีที่เก่าเกินไป
Bash 4+ ตัวอย่าง หมายเหตุ: การไม่ใช้เครื่องหมายคำพูดจะทำให้เกิดปัญหาเมื่อคำต่างๆมีช่องว่าง ฯลฯ อ้างถึงใน Bash, IMO เสมอ
นี่คือตัวอย่างบางส่วนใน Bash 4+:
ตัวอย่างที่ 1 ตรวจสอบว่า 'ใช่' ในสตริง (ไม่คำนึงถึงขนาดตัวพิมพ์):
if [[ "${str,,}" == *"yes"* ]] ;then
ตัวอย่างที่ 2 ตรวจสอบว่า 'ใช่' ในสตริง (ไม่คำนึงถึงขนาดตัวพิมพ์):
if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then
ตัวอย่างที่ 3 ตรวจสอบว่า 'ใช่' ในสตริง (เล็กหรือใหญ่):
if [[ "${str}" == *"yes"* ]] ;then
ตัวอย่างที่ 4 ตรวจสอบว่า 'ใช่' ในสตริง (เล็กหรือใหญ่):
if [[ "${str}" =~ "yes" ]] ;then
ตัวอย่างที่ 5 การจับคู่แบบตรงทั้งหมด (ตัวพิมพ์เล็กและใหญ่):
if [[ "${str}" == "yes" ]] ;then
ตัวอย่างที่ 6 การจับคู่แบบตรงทั้งหมด (ตัวพิมพ์เล็กและตัวพิมพ์ใหญ่):
if [[ "${str,,}" == "yes" ]] ;then
ตัวอย่างที่ 7 การจับคู่แบบตรงทั้งหมด:
if [ "$a" = "$b" ] ;then
สนุก.
if [ "$a"="$b" ]หรือไม่ทำงาน ... ไม่สามารถมีช่องว่างรอบเท่ากับ