Bash - การจัดการสตริงอย่างต่อเนื่อง


11
#!/bin/bash

FILE="$(basename "$1")"
FILE="${FILE/%.jpeg/.jpg}"

อย่างไรก็ตามมีกาวสองบรรทัดนี้รวมกันเป็นหนึ่งซับ?

คำตอบ:


12

FILE=$(basename "${1/%.jpeg/.jpg}") ทำงานให้ฉัน

ทดสอบ:

bash-$ ./test.sh /tmp/foo.jpeg
foo.jpg

เนื้อหาของสคริปต์:

bash-$ cat test.sh 
#!/usr/bin/bash

FILE=$(basename "${1/%.jpeg/.jpg}")

echo "$FILE"

เนื่องจากทั้งสองเส้นมีความสามารถในการแลกเปลี่ยนกันการแก้ปัญหานี้จึงsedเป็นสิ่งที่เรียบร้อยที่สุด ...
gsklee

11

คุณไม่สามารถซ้อนการขยายใน bash (หรือเป็น ksh, ash และ shell อื่น ๆ นอกเหนือจาก zsh) นี่เป็นเพียงข้อ จำกัด ด้านเครื่องสำอางเนื่องจากตามที่คุณแสดงคุณสามารถกำหนดนิพจน์กลางให้กับตัวแปรชั่วคราว มันน่ารำคาญนิดหน่อยสำหรับหนึ่ง liners แต่ในสคริปต์มัน arguably ดีกว่าสำหรับการอ่าน

คุณสามารถหลีกเลี่ยงการใช้ยูทิลิตี้ภายนอกbasenameและใช้โครงสร้างการจัดการสตริงแทน:

FILE="${1##*/}"; FILE="${FILE/%.jpeg/.jpg}"

นี่มันเกิดขึ้นที่คุณสามารถเขียนสคริปต์ของคุณไปใส่แทนคำสั่งด้านนอก นั่นไม่ใช่ปรากฏการณ์ทั่วไปหรือคุณไม่ได้อะไรนอกเหนือไปจากความรู้สึกแบบหนึ่งซับ

Zsh ให้ดีขึ้นหรือแย่ลงจะช่วยให้คุณขยายการขยาย:

FILE=${$(basename $1)/%.jpeg/.jpg}    # using basename
FILE=${${1##*/}/%.jpeg/.jpg}          # using string rewriting

หรือคุณสามารถใช้โครงสร้างภายในของ zsh แทนbasename:

FILE=${${1:t}/%.jpeg/.jpg}

4

ฉันจะไปที่:

FILE=$(basename $1 .jpeg).jpg

พารามิเตอร์ที่สองเพื่อ basename เป็นคำต่อท้ายที่จะลบออกจากชื่อไฟล์ (ดูman basename)


3

คุณสามารถใช้sedคำสั่งเดียวดังต่อไปนี้:

FILE=$(sed 's/.*\///;s/\.jpeg$/.jpg/' <<<"$1")

2

การรวมsedสิ่งนี้ควรทำเคล็ดลับ:

FILE="$(basename "$1" | sed s/\.jpeg$/.jpg/)"

(สิ่งนี้ไม่ตอบคำถามของคุณอย่างแน่นอนเพราะฉันทำไม่ได้ไม่แน่ใจว่าเป็นไปได้หรือไม่)


1

Bash ${}สร้างทำงานกับชื่อตัวแปรดังนั้นจึงไม่มีวิธีการฝังคำสั่งโดยตรง วิธีการของ @ sr_ เป็นทางเลือกถ้าคุณไม่สนใจทางแยก


1

เส้น

FILE=$(basename "${1/%.jpeg/.jpg}")

สามารถทำให้สั้นลงและทำให้พกพาสะดวกมากขึ้นด้วย

FILE=$(basename "${1%.jpeg}.jpg")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.