ช่วงเทศกาลถึงแล้ว — ร้านค้าตกแต่งสีสัน เรารู้สึกอยากช้อปปิ้ง โดยเฉพาะซื้อของขวัญ! (ของขวัญให้ตัวเองก็ยังนับว่าเป็นของขวัญ)
เพื่อไม่ให้สับสน เราควรทำ Gift Lists — Bash ช่วยได้!
Brace Expansion
นี่ ไม่ใช่ Braces: ()
นี่ ไม่ใช่ Braces: []
นี่คือ Braces: {}
Braces บอก Bash ให้ทำงานกับ String(s) ระหว่างวงเล็บ — หลาย Strings คั่นด้วย Comma: {a,b,c} สามารถเพิ่ม Preamble และ Postscript ต่อท้ายแต่ละผลลัพธ์ได้ — ประหยัดการพิมพ์ Path/Extension ซ้ำ
สร้าง Gift Lists ทีละคน
คำสั่งต่อไปนี้เทียบเท่ากัน:
touch /home/me/gift-lists/Amy.txt /home/me/gift-lists/Bryan.txt /home/me/gift-lists/Charlie.txt
touch /home/me/gift-lists/{Amy,Bryan,Charlie}.txt
tree gift-lists
/home/me/gift-lists ├── Amy.txt ├── Bryan.txt └── Charlie.txt
โอ้ "Bryan" สะกดผิด (ควรเป็น Bryan → Brian) แก้ได้ง่าย:
mv /home/me/gift-lists/{Bryan,Brian}.txt
# renamed '/home/me/gift-lists/Bryan.txt' -> '/home/me/gift-lists/Brian.txt'
Shell Parameter Expansions
Shell Parameter Expansion ใช้ Braces ครอบ Parameter เพื่อ Manipulate/Substitute Text
ของขวัญพื้นฐานทุกคน (Variable)
STUFF=$'socks\nlump of coal\nwhite chocolate'
echo "$STUFF"
# socks
# lump of coal
# white chocolate
เพิ่มรายการนี้ในทุกไฟล์ด้วย tee (ช่วยให้ echo และ expansion ทำงานร่วมกัน):
echo "$STUFF" | tee {Amy,Brian,Charlie}.txt
cat {Amy,Brian,Charlie}.txt
# socks / lump of coal / white chocolate (ซ้ำ 3 ครั้ง)
Pattern Match Substitution
"Lump of coal" ไม่น่ารัก — แทนที่ด้วย Pattern Match Substitution ${parameter/pattern/string}:
echo "${STUFF/lump of coal/candy cane}" | tee {Amy,Brian,Charlie}.txt
cat {Amy,Brian,Charlie}.txt
# socks / candy cane / white chocolate (ทุกไฟล์)
แทนที่ครั้งแรกเจอ — แทนที่ทั้งหมดใช้ ${parameter//pattern/string} — ตัวแปร $STUFF เดิมไม่เปลี่ยน (Reusable)
Substrings
เพิ่ม Chocolate ธรรมดา เผื่อใครไม่ชอบ White Chocolate — ใช้ Substring ${parameter:offset} ดึงคำสุดท้าย ("chocolate" = 9 ตัวอักษร):
echo "${STUFF: -9}" | tee -a {Amy,Brian,Charlie}.txt
cat {Amy,Brian,Charlie}.txt
# เพิ่ม chocolate ท้ายแต่ละไฟล์
Substring อื่นๆ:
| ทำได้ | Syntax |
|---|---|
| Substring จากตำแหน่ง n เป็นต้นไป | ${parameter:n} |
| Substring ยาว x ตัวอักษร เริ่มที่ n | ${parameter:n:x} |
Testing Variables
เช็คว่าตัวแปรมีอยู่ไหม — ${parameter:?word} เขียน word ไป stderr และ exit หากไม่มี parameter:
echo "${amy:?no such}"
# bash: amy: no such
ลอง brian:
echo "${brian:?no such}"
# Lederhosen
Expansions อื่นๆ สำหรับ Default Values:
| ทำได้ | Syntax |
|---|---|
| แทน word หาก unset/null | ${parameter:-word} |
| แทน word หาก ไม่ใช่ unset/null | ${parameter:+word} |
| Assign word หาก unset/null | ${parameter:=word} |
เปลี่ยน Case
Brian อยากได้ Lederhosen — เพิ่มในไฟล์ Brian ด้วย Uppercase ${parameter^^pattern}:
echo "${brian^^}" >> Brian.txt
cat Brian.txt
# ... LEDERHOSEN
Case Expansions อื่นๆ:
| ทำได้ | Syntax |
|---|---|
| ตัวแรก Uppercase | ${parameter^pattern} |
| ตัวแรก Lowercase | ${parameter,pattern} |
| ทั้งหมด Lowercase | ${parameter,,pattern} |
Expanding Arrays
สร้าง Array ของของขวัญ:
gifts=(sweater gameboy wagon pillows chestnuts hairbrush)
ใช้ Substring Expansion ${parameter:offset:length} แบ่งให้แต่ละคน — printf ช่วย Newlines:
printf '%s\n' "${gifts[@]:0:2}" >> Amy.txt
printf '%s\n' "${gifts[@]:2:2}" >> Brian.txt
printf '%s\n' "${gifts[@]: -2}" >> Charlie.txt
ผลลัพธ์สุดท้าย:
Amy.txt: socks candy cane white chocolate chocolate sweater gameboy
Brian.txt: socks candy cane white chocolate chocolate LEDERHOSEN wagon pillows
Charlie.txt: socks candy cane white chocolate chocolate chestnuts hairbrush
ตอนนี้มี Gift Lists ครบครันและ Personalized แล้ว — ขอบคุณ Bash! (แค่ช้อปปิ้งให้ด้วยน่าจะดีกว่า)