เปรียบเทียบสองสตริงใน Bash


22

ฉันมีifบล็อกต่อไปนี้ในสคริปต์ทุบตีของฉัน:

if [ ${PACKAGENAME} -eq kakadu-v6_4-00902C ]; then
  echo "successfully entered if block!!"
fi

การดำเนินการสคริปต์ไม่ได้เข้ามาของฉันifบล็อกแม้ว่าจะมีค่าเท่ากับ$PACKAGENAME kakadu-v6_4-00902Cผมทำอะไรผิดหรือเปล่า?


9
-eqเป็นจริงสำหรับจำนวนเต็มคุณต้องการทดสอบสตริงหรือ regex ( ==หรือ=~): mywiki.wooledge.org/BashGuide/TestsAndConditionals
jasonwryan

ขอบคุณjasonwryanฉันจะดูที่ทรัพยากรนี้!
DemiSheep

คำตอบ:


31

-eq เป็นตัวดำเนินการทางคณิตศาสตร์ซึ่งเปรียบเทียบสองตัวเลข

ใช้=(พกพา / มาตรฐานsh) =~หรือ==แทน

ใช้เครื่องหมายคำพูดเพราะถ้า${PACKAGENAME}มีอักขระช่องว่างหรืออักขระตัวแทนมันจะถูกแบ่งออกเป็นหลายอาร์กิวเมนต์ซึ่งทำให้การ[ดูอาร์กิวเมนต์มากกว่าที่ต้องการ ดูที่นี่รายการของข้อผิดพลาดทุบตีทั่วไป

if [ "${PACKAGENAME}" = 'kakadu-v6_4-00902C' ]; then
    echo "successfully entered if block!!"
fi

ดูman bashการค้นหา ( /) CONDITIONAL EXPRESSIONSสำหรับ


1
Ah! ขอขอบคุณ! มันได้ผล! เห็นได้ชัดว่าฉันเป็นมือใหม่ที่นี้ ฉันขอบคุณสำหรับความช่วยเหลือของคุณ!
DemiSheep

2
คุณเคยดูที่tldp.org/LDP/Bash-Beginners-Guide/htmlหรือไม่ เป็นคำแนะนำทุบตีที่ดีมากและจะช่วยให้คุณมีตัวอย่างและการสอบ :)
polym

1
ขอบคุณpolymฉันจะดูขอบคุณสำหรับทรัพยากร! ฉันจะเปิดแท็บนั้นขึ้นถัดจากคู่มือ VI ของฉัน :)
DemiSheep

4
ภายในเครื่องหมายวงเล็บคู่จะไม่มีการแบ่งคำใด ๆ ดังนั้น[[ $PACKAGENAME == "kakadu..." ]]ตกลง
เกล็นแจ็คแมน

4
@glennjackman ระวัง แต่ที่แม้จะอยู่ในวงเล็บคู่ที่คุณต้องการคำพูดสองรอบการขยายตัวแปรทางด้านขวามือของ=, ==และ!=เพราะข้างเคียงที่เป็นรูปแบบไม่สตริง ตัวอย่างเช่นfoo='*'; [[ whatever = $foo ]]เป็นจริง
Gilles 'หยุดความชั่วร้าย'

6

แทนที่-eqด้วย== ดังนั้นถ้าบล็อกของคุณจะเป็นนี้: -

if [ ${PACKAGENAME} == kakadu-v6_4-00902C ]; then

        echo "successfully entered if block!!"

fi

5
อย่าลืมอ้างอิง! ดูที่นี่ทำไม: mywiki.wooledge.org/BashPitfalls#A.5B_.24foo_.3D_.22bar.22_.5D
polym

@ polym เฮ้ขอบคุณ แต่ฉันเพิ่งให้รุ่น minimalist ที่ทำงาน;): D
beginer

4

วิธีอื่นคือลบล้างพวกเขา:

: ${PACKAGENAME:?'$PACKAGENAME variable is empty!'} #emits error and exits
[ -z "${PACKAGENAME#kakadu-v6_4-00902C}" ] || { #if var - str not empty do block
    echo '$PACKAGENAME is not kakadu-v6_4-00902C' 
    exit 1
} >&2

การทดสอบครั้งแรกบล็อกข้างต้นถ้า"$PACKAGENAME"มีค่าใด ๆ และถ้าไม่ได้ออกจากที่มีข้อผิดพลาดและสะท้อนไป?'this'} stderrหากเปลือกหลักยังคงมีอยู่การทดสอบจะผ่านไปและจะทำการทดสอบครั้งถัดไปหากลบสตริง 'kakadu ... ' ออกจากตัวแปรผลลัพธ์จะเป็น-zสตริงว่าง หากไม่เป็นเช่นนั้นจะส่งข้อผิดพลาดอีกครั้งและออกจากเชลล์ หากเชลล์ของคุณยังคงมีอยู่ ณ จุดนี้สิ่งใดหลังจากบล็อกจะดำเนินการมิฉะนั้นมันจะไม่

อาจเป็นไปได้ว่าการเรียงลำดับของสิ่งนี้ดีที่สุดในฟังก์ชั่น ชอบ:

argeq() ( i= : ${2?^MERR: not enough parameters!} #$#>=2 || quit w/ err ^M == \r
    z() { return $((${#1}>0)) ; } #return 1 if ${#1}>0 else 0
    until z "${2+?}" $((i=i+1)) #until $2 is not set...
    do  ! z "$1" && z "${1#"$2"}" || #$1 != '' && $1 - $2 == '' or...
        exit $((i${1:++1})) #exit $? == failed arg count
    shift ; done #shift away one param ; continue loop
)

ด้วยฟังก์ชันนั้นคุณสามารถระบุอาร์กิวเมนต์ได้มากเท่าที่ระบบของคุณจะอนุญาต ถ้าคุณให้น้อยกว่า 2 มันจะกลับมาที่ 1 stderrและปล่อยข้อความไปยัง หากคุณให้ข้อโต้แย้งอย่างน้อย 2 ข้อจะถือว่าเป็นสตริงทั้งหมดและส่งคืน 0 หากทั้งหมดเหมือนกันและไม่เป็นโมฆะมันจะส่งคืนหมายเลขอาร์กิวเมนต์ที่ไม่สามารถตรวจสอบได้ในตอนแรก

ในกรณีของคุณสามารถใช้เช่น:

{   
    PACKAGENAME='kakadu-v6_4-00902C'
    argeq "$PACKAGENAME" kakadu-v6_4-00902C &&
        echo "kakadu-v6_4-00902C == $PACKAGENAME" ||
        echo failure
    ! argeq "${PACKAGENAME#*-}" kakadu-v6_4-00902C &&
        echo "kakadu-v6_4-00902C != ${PACKAGENAME#*-}" ||
        echo failure
}

###OUTPUT###
kakadu-v6_4-00902C == kakadu-v6_4-00902C
kakadu-v6_4-00902C != v6_4-00902C

เพื่อแสดงเพิ่มเติมฉันจะเขียนฟังก์ชั่นอื่น:

aeqecho() { i=$((i+1)) #inc for line#
    argeq "$@" && echo "$i : yay" || #allswell or
    ! e=$? ${2+:} return || #save $?; ! exclusive || to drop ERRs
    echo "$i : shite - arg$e failed" #report failure
}

การสาธิต:

{  i= s=string
   aeqecho $s #1
   aeqecho $s $s #2
   aeqecho "$s $s" #3
   aeqecho "$s $s" "${s} string" #4
   aeqecho "${s}1" $s string #5
   aeqecho "" "" "" #6
   aeqecho "" "$s" $s #7
   aeqecho 1 "${s#$s}1" $((2-1)) #8                     
   aeqecho $s $s $s $s $s $s $s $s $s $s $s $s stng #9  
   aeqecho $s $s $s $s $s $s $s $s $s $s $s $s string #10
}  

เอาท์พุท:

ERR: not enough parameters!
2 : yay
ERR: not enough parameters!
4 : yay
5 : shite - arg2 failed
6 : shite - arg1 failed
7 : shite - arg1 failed
8 : yay
9 : shite - arg13 failed
10 : yay
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.