ฉันมีตัวแปรvar
ในสคริปต์ Bash ถือสตริงเช่น:
echo $var
"some string.rtf"
ฉันต้องการลบอักขระ 4 ตัวสุดท้ายของสตริงนี้และกำหนดผลลัพธ์ให้กับตัวแปรใหม่var2
ดังนั้น
echo $var2
"some string"
ฉันจะทำสิ่งนี้ได้อย่างไร
ฉันมีตัวแปรvar
ในสคริปต์ Bash ถือสตริงเช่น:
echo $var
"some string.rtf"
ฉันต้องการลบอักขระ 4 ตัวสุดท้ายของสตริงนี้และกำหนดผลลัพธ์ให้กับตัวแปรใหม่var2
ดังนั้น
echo $var2
"some string"
ฉันจะทำสิ่งนี้ได้อย่างไร
คำตอบ:
ก่อนอื่นคุณควรมีความชัดเจนเกี่ยวกับสิ่งที่คุณต้องการ ถ้าคุณรู้ว่าปลายสตริงใน.rtf
และคุณต้องการที่จะลบคุณสามารถใช้.rtf
var2=${var%.rtf}
หากคุณไม่ได้รู้ว่าสิ่งที่ต่อท้ายเป็น แต่คุณต้องการที่จะลบทุกอย่างเริ่มต้นด้วยสุดท้ายแล้วคุณสามารถใช้.
var2=${var%.*}
ถ้าคุณเพียงต้องการที่จะให้ทุกอย่างขึ้นกับครั้งแรกที่คุณสามารถใช้.
var2=${var%%.*}
ตัวเลือกสองตัวสุดท้ายเหล่านั้นมีผลลัพธ์เหมือนกันหากมีเพียงช่วงเวลาเดียว แต่หากอาจมีมากกว่าหนึ่งตัวคุณควรตัดสินใจเลือกสิ่งที่คุณต้องการ
หากคุณต้องการลบจำนวนอักขระที่แน่นอนเสมอนี่คือตัวเลือกบางตัว
คุณระบุ bash เป็นพิเศษดังนั้นเราจะเริ่มด้วย bash builtins var2=${var%????}
หนึ่งซึ่งมีการทำงานที่ยาวที่สุดคือไวยากรณ์ต่อท้ายกำจัดเดียวกันผมใช้ข้างต้นที่จะเอาสี่ตัวอักษรใช้ คุณต้องลบเครื่องหมายคำถามหนึ่งตัวต่อหนึ่งตัวอักษรดังนั้นสิ่งนี้จะยากขึ้นสำหรับความยาวสตริงย่อยที่ใหญ่
เล็กน้อยที่ใหม่กว่า substring var2=${var::${#var}-4}
สกัด: ที่นี่คุณสามารถใส่หมายเลขใดก็ได้4
เพื่อลบจำนวนอักขระที่แตกต่างกัน (ตัว${#var}
ถูกแทนที่ด้วยความยาวของสตริงดังนั้นจึงขอให้เก็บอักขระ (ความยาว - 4) ตัวแรก)
รุ่นใหม่ของทุบตี (เฉพาะ 4+ ซึ่งหมายความว่าคนที่มาพร้อมกับ MacOS จะไม่ทำงาน) var2=${var::-4}
ช่วยให้คุณลดความซับซ้อนที่จะเพียงแค่
หากคุณไม่ได้ใช้ทุบตีจริง ๆ แต่เชลล์ชนิด POSIX อื่น ๆ การลบคำต่อท้ายจะยังคงใช้ได้แม้อยู่ในเส้นประเก่าแบบธรรมดา ใน zsh พวกเขาทุกงาน แต่คุณต้องใส่0
ระหว่างทวิภาคนี้var2=${var:0:-4}
ฯลฯ ใน ksh คุณต้อง 0 และยังมีการใช้อย่างชัดเจนความยาว 4 var2=${var:0:${#var}-4}
แสดงออก:
แน่นอนคุณสามารถใช้การทดแทนคำสั่งเพื่อทำมันด้วยความช่วยเหลือของโปรแกรมอรรถประโยชน์; มีมากมายที่จะทำงานได้ แต่สิ่งที่ชอบvar2=$(cut -c -4 <<<"$var")
น่าจะเป็นตัวเลือกที่สั้นที่สุด
คุณสามารถทำสิ่งนี้:
#!/bin/bash
v="some string.rtf"
v2=${v::-4}
echo "$v --> $v2"
bash
4+ ${v::${#v}-4}
แต่ในรุ่นก่อนหน้านี้คุณสามารถใช้อีกเล็กน้อย
${v::-4}
croaks "zsh: คาดว่าจะปิดวงเล็บ" แต่คำตอบของ @fredtantini ด้านล่าง${v:0:-4}
ใช้ได้ดี
${var%????}
ในการลบอักขระสี่ตัวจากจุดสิ้นสุดของการใช้สตริง
ในการลบทุกอย่างหลังจากสุดท้ายการใช้งาน.
${var%.*}
${var#????}
ว่า
สิ่งที่ทำงานให้ฉันคือ:
echo "hello world" | rev | cut -c5- | rev
# hello w
แต่ฉันใช้มันเพื่อตัดเส้นในไฟล์ดังนั้นนั่นจึงเป็นเหตุผลที่ทำให้ดูเคอะเขิน การใช้งานจริงคือ:
cat somefile | rev | cut -c5- | rev
cut
เพียงทำให้คุณได้รับการตัดแต่งจากตำแหน่งเริ่มต้นซึ่งไม่ดีหากคุณต้องการแถวความยาวผันแปร ดังนั้นวิธีนี้จึงย้อนกลับ ( rev
) สตริงและตอนนี้เราเกี่ยวข้องกับตำแหน่งสิ้นสุดของมันจากนั้นใช้cut
ตามที่กล่าวไว้และย้อนกลับ (อีกครั้งrev
) กลับไปเป็นคำสั่งเดิม
rev
ฝืนเส้นไม่ใช่สาย echo $SOME_VAR | rev | ...
อาจจะไม่ทำงานตามที่คาดไว้
ใช้ตัวแปรการขยาย / Substring แทน :
$ {var / รูปแบบ% / เปลี่ยน}
หากส่วนต่อท้ายของ var ตรงกับรูปแบบให้เปลี่ยนทดแทนสำหรับรูปแบบ
ดังนั้นคุณสามารถทำได้:
~$ echo ${var/%????/}
some string
อีกวิธีหนึ่งคือ
หากคุณมีตัวอักษร 4 ตัวเสมอ
~$ echo ${var/.rtf/}
some string
หากมันสิ้นสุดใน.xyz
:
~$ echo ${var%.*}
some string
คุณยังสามารถใช้ความยาวของสตริง:
~$ len=${#var}
~$ echo ${var::len-4}
some string
หรือเพียงแค่ echo ${var::-4}
len=${#var}; echo ${var::len-4}
อาจจะลงไปecho ${var:0:-4}
:-) แก้ไข: หรือเป็น @iyonizer ชี้ให้เห็นเพียงแค่echo ${var::-4}
...
คุณสามารถใช้ sed
sed 's/.\{4\}$//' <<< "$var"
ตัวอย่าง:
$ var="some string.rtf"
$ var1=$(sed 's/.\{4\}$//' <<< "$var")
$ echo $var1
some string
var2
อย่างไร
ฉันลองสิ่งต่อไปนี้และได้ผลกับฉัน:
#! /bin/bash
var="hello.c"
length=${#var}
endindex=$(expr $length - 4)
echo ${var:0:$endindex}
เอาท์พุท: hel
หวังว่าตัวอย่างด้านล่างจะช่วยได้
echo ${name:0:$((${#name}-10))}
-> ${name:start:len}
start
เป็นจุดเริ่มต้นของสตริงlen
คือความยาวของสตริงที่ต้องถูกลบออกตัวอย่าง:
read -p "Enter:" name
echo ${name:0:$((${#name}-10))}
เอาท์พุท:
Enter:Siddharth Murugan
Siddhar
หมายเหตุ: Bash 4.2 เพิ่มการสนับสนุนสำหรับสตริงย่อยเชิงลบ
สิ่งนี้ใช้ได้สำหรับฉันโดยการคำนวณขนาดของสตริง
เป็นเรื่องง่ายที่คุณจะต้องสะท้อนมูลค่าที่คุณต้องการคืนจากนั้นจัดเก็บตามด้านล่าง
removechars(){
var="some string.rtf"
size=${#var}
echo ${var:0:size-4}
}
removechars
var2=$?
สตริงบางส่วน
ในกรณีนี้คุณสามารถใช้ชื่อไฟล์สมมติว่าคุณมีคำต่อท้ายเหมือนกันกับไฟล์ที่คุณต้องการลบ
ตัวอย่าง:
basename -s .rtf "some string.rtf"
นี่จะส่งคืน "สตริงบางส่วน"
หากคุณไม่ทราบคำต่อท้ายและต้องการให้ลบทุกอย่างหลังจากนั้นและรวมถึงจุดสุดท้าย:
f=file.whateverthisis
basename "${f%.*}"
ส่งออก "ไฟล์"
หมายถึงการสับ คือสิ่งที่คุณกำลังจะสับ * เป็นสัญลักษณ์แทน