bash: จะใช้การปรับแต่งสตริงหลายรายการ (การขยายพารามิเตอร์) ในขั้นตอนเดียวได้อย่างไร?

Aug 15 2020

ฉันมีstring=substr1-substr2-substr3.substr4สตริงย่อยที่มีความยาวผันแปรได้ ฉันต้องการแยกsubstr3ออกstringและกำลังคิดว่าจะทำโดยใช้การขยาย${string##pattern}และการ${string%pattern}จัดการสตริง เมื่อใช้วิธีนี้เป็นที่ชัดเจนว่าฉันจำเป็นต้องเรียกใช้${string##*-}และดำเนินการ${string%.*}กับส่วนขยายที่เป็นผลลัพธ์หรือในทางกลับกัน คำถามของฉันคือ:

  1. นี่คือทางเลือกที่ดีที่สุดหรือไม่?
  2. ถ้าใช่ฉันจะเรียกใช้ทั้งสองอย่างในขั้นตอนเดียวได้อย่างไร เมื่อฉันพยายามทำบางสิ่งบางอย่างเช่น${string##*-${string%.*}}หรือ${string%.*${string##*-}}ฉันเพิ่งกลับสตริงเต็ม ฉันรู้ว่าฉันสามารถทำการแยกในสองขั้นตอนได้เสมอโดยกำหนดตัวแปรกลางให้กับผลลัพธ์ของขั้นตอนแรกจากนั้นจัดการกับสิ่งนั้น แต่ฉันต้องการทำในขั้นตอนเดียว ฉันจะไปเกี่ยวกับเรื่องนี้ได้อย่างไร?

เทีย!

คำตอบ

2 ilkkachu Aug 15 2020 at 20:39

ให้

string=substr1-substr2-substr3.substr4

${string%.*} คือ

substr1-substr2-substr3

ดังนั้น${string##*-${string%.*}}คือ

${string##*-substr1-substr2-substr3}

ซึ่งหมายถึงการเอาออกจากจุดเริ่มต้นของทุกอย่างและรวมถึงstring -substr1-substr2-substr3แต่ไม่มีสตริงย่อยดังกล่าวstringเนื่องจากไม่มีเส้นประอยู่ข้างหน้าsubstr1ดังนั้นคุณจึงได้สตริงต้นฉบับ

สิ่งที่คุณอาจต้องการคือ

string=substr1-substr2-substr3.substr4
result="${string%.*}" result="${result##*-}"

ซึ่งนำไปสู่การcontaingresultsubstr3

ใน Zsh คุณสามารถทำได้ในขั้นตอนเดียวแต่ใช้ไม่ได้ใน Bashresult=${${string%.*}##*-}

ใน Bash คุณถูก จำกัด ให้ใช้การขยายทางด้านขวาของ#หรือ%และนั่นไม่ได้ช่วยคุณในส่วนนี้เนื่องจากคุณต้องลบส่วนต่างๆออกจากทั้งจุดเริ่มต้นและจุดสิ้นสุดของสตริง


หรือหาก$stringไม่มีอักขระขึ้นบรรทัดใหม่คุณสามารถใช้

IFS=.- read -r a b c d <<< "$string"

และอ่านจากsubstr3c

ในกรณีที่ว่าขึ้นอยู่กับเปลือกและขนาดของสตริงเนื้อหาของ$stringจะถูกเก็บไว้ทั้งในแฟ้มชั่วคราวหรือป้อนผ่านท่อที่จะอ่านบรรทัดแรกจากแยกมันตามread$IFS