วิธีการส่งออกสตริงที่คั่นด้วยเครื่องหมายจุลภาคโดยใช้การขยาย bash brace


17

ฉันต้องการ

$ echo a{b,c,d}

เพื่อส่งออกรายการคั่นด้วยเครื่องหมายจุลภาคเช่น

ab,ac,ad

แทนการส่งออกปกติ

ab ac ad

วิธีที่ง่ายที่สุดในการทำเช่นนั้นในบรรทัดคำสั่งคืออะไร?

คำตอบ:


9

สมมติว่าองค์ประกอบไม่มีช่องว่างคุณสามารถแปลช่องว่างเป็นจุลภาค:

echo a{b,c,d} | tr ' ' ,

ซึ่งผลิต:

ab,ac,ad

คุณยังสามารถใช้ช่วงที่มีตัวอักษร:

echo a{b..d} | tr ' ' ,

สิ่งนี้มีประโยชน์อย่างยิ่งหากคุณต้องการช่วงที่กว้างขึ้น


13

ดูเหมือนว่า bash ไม่ได้ใช้ $ IFS เพื่อเข้าร่วมคำที่สร้างขึ้น อีกเทคนิคหนึ่งก็คือการเก็บคำที่สร้างขึ้นในอาร์เรย์และจากนั้น $ IFS จะเล่น:

ฉันจะใช้ subshell ดังนั้นฉันจะไม่เปลี่ยน IFS ของ shell นี้: เลือกหนึ่งอัน

( words=( a{b,c,d} ); IFS=,; echo "${words[*]}" )
( set -- a{b,c,d}; IFS=,; echo "$*" )

ที่ปล่อยสตริงคั่นด้วยเครื่องหมายจุลภาคเพื่อ stdout ถ้าคุณต้องการที่จะจับมัน:

joined=$( set -- a{b,c,d}; IFS=,; echo "$*" )

มันไม่ได้เข้าร่วมสร้างคำที่ทุกคน นั่นคือประเด็นทั้งหมดมันขยายออกไปเพื่อแยกคำ
Stéphane Chazelas


2

ขยายองค์ประกอบตามที่คุณแสดงแล้ววนรอบองค์ประกอบเหล่านั้นเพิ่มเครื่องหมายจุลภาคให้กับทั้งหมดยกเว้นการวนซ้ำครั้งแรก:

for i in a{b,c,d}; do
  u="${u:+$u, }$i"
done
echo "$u"

ผลลัพธ์:

ab, ac, ad

ดูเปลี่ยนตัวพารามิเตอร์ทุบตี


1

นี่เป็นวิธีการทุบตีเท่านั้น

(IN=$(echo a{b,c,d}); echo ${IN// /,})
# ab,ac,ad

ส่วนก่อนเครื่องหมายอัฒภาคab ac adจะกำหนดให้กับตัวแปรINและส่วนที่สองใช้การค้นหาและแทนที่เพื่อเปลี่ยนช่องว่างทั้งหมดเป็นเครื่องหมายจุลภาค //หมายถึงการแข่งขันทั้งหมดไม่เพียง แต่เป็นครั้งแรก

ทำทั้งหมดใน subshell (วงเล็บล้อมรอบ) เพื่อไม่สร้างมลภาวะเนมสเปซของคุณ


1

เป็นที่น่าสังเกตว่าในบริบทจำนวนมากจุลภาคต่อท้ายเป็นที่ยอมรับในรายการดังกล่าว หากยอมรับคอมม่าต่อท้ายวิธีที่ง่ายที่สุดในการจัดการการทดแทนคือprintf:

some-command "$(printf %s, a{b,c,d} )"

(ซึ่งsome-commandเป็นคำสั่งที่ทำงานในรายการที่คั่นด้วยเครื่องหมายจุลภาคและไม่สนใจเกี่ยวกับเครื่องหมายจุลภาคต่อท้าย)

จริงๆแล้วแม้ว่าคุณจะต้องไม่มีจุลภาคต่อท้ายคุณสามารถใช้printf; คุณเพียงแค่ต้องระบุจำนวนของอาร์กิวเมนต์ที่คุณคาดหวังซึ่งทำให้ clumsier สำหรับรายการที่ยาวมาก:

some-command "$(printf %s,%s,%s a{b,c,d} )"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.