Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม Bash

Bash Brace Expansion ที่มีประสิทธิภาพ: สร้างรายการเร็วๆ

ช่วงเทศกาลถึงแล้ว — ร้านค้าตกแต่งสีสัน เรารู้สึกอยากช้อปปิ้ง โดยเฉพาะซื้อของขวัญ! (ของขวัญให้ตัวเองก็ยังนับว่าเป็นของขวัญ)

เพื่อไม่ให้สับสน เราควรทำ 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! (แค่ช้อปปิ้งให้ด้วยน่าจะดีกว่า)