Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม BASH

การขยาย Bash และเชลล์:การทำรายการแบบขี้เกียจ

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

เพื่อที่สิ่งนี้จะไม่บ้าไปเสียทั้งหมด คุณควรทำรายการของขวัญ Bash ช่วยได้

ส่วนขยายรั้ง

นี่ไม่ใช่เครื่องหมายวงเล็บ:()

ไม่ใช่เหล่านี้:[]

เหล่านี้ มีเครื่องหมายวงเล็บ:{}

วงเล็บปีกกาบอกให้ Bash ทำบางสิ่งกับสตริงหรือสตริงที่กำหนดเองซึ่งพบระหว่างพวกเขา หลายสตริงคั่นด้วยเครื่องหมายจุลภาค:{a,b,c} . คุณยังสามารถเพิ่มคำนำและคำลงท้ายที่ไม่บังคับเพื่อแนบไปกับผลลัพธ์ที่ขยายแต่ละรายการ ส่วนใหญ่ วิธีนี้จะช่วยประหยัดการพิมพ์บางอย่างได้ เช่น กับเส้นทางไฟล์และนามสกุลทั่วไป

มาทำรายการสำหรับแต่ละคนที่เราอยากจะมอบให้กันเถอะ คำสั่งต่อไปนี้เทียบเท่า:

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

แย่จัง "ไบรอัน" สะกดชื่อเขาด้วย "i" ฉันสามารถแก้ไขได้

mv /home/me/gift-lists/{Bryan,Brian}.txt

renamed '/home/me/gift-lists/Bryan.txt' -> '/home/me/gift-lists/Brian.txt'

การขยายพารามิเตอร์ของเชลล์

การขยายพารามิเตอร์ของเชลล์ช่วยให้เราเปลี่ยนแปลงพารามิเตอร์ที่อยู่ในวงเล็บปีกกาได้ทุกประเภท เช่น จัดการและแทนที่ข้อความ

มีถุงเท้ายาวสองสามตัวที่ผู้ได้รับของขวัญจากเราสมควรได้รับ ให้มันเป็นตัวแปร:

STUFF=$'socks\nlump of coal\nwhite chocolate'

echo "$STUFF"
socks
lump of coal
white chocolate

ตอนนี้เพื่อเพิ่มรายการเหล่านี้ลงในแต่ละรายการของเราด้วยความช่วยเหลือจาก tee คำสั่งรับ echo และส่วนเสริมให้เล่นได้ดี

echo "$STUFF" | tee {Amy,Brian,Charlie}.txt

cat {Amy,Brian,Charlie}.txt

socks
lump of coal
white chocolate
socks
lump of coal
white chocolate
socks
lump of coal
white chocolate

การแทนที่การจับคู่รูปแบบ

ในความคิดที่สอง บางทีก้อนถ่านอาจไม่ใช่ของกำนัลที่ดีนัก คุณสามารถแทนที่ด้วยสิ่งที่ดีกว่าโดยใช้การแทนที่การจับคู่รูปแบบในรูปแบบของ ${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
socks
candy cane
white chocolate
socks
candy cane
white chocolate

สิ่งนี้แทนที่ตัวอย่างแรกของ "ก้อนถ่านหิน" ด้วย "อ้อยขนม" หากต้องการแทนที่อินสแตนซ์ทั้งหมด (หากมีหลายรายการ) ให้ใช้ ${parameter//pattern/string} . สิ่งนี้ไม่เปลี่ยน $STUFF . ของเรา ตัวแปร ดังนั้นเรายังคงสามารถใช้รายการเดิมสำหรับคนที่ซุกซนในภายหลังได้

สตริงย่อย

ในขณะที่เรากำลังปรับปรุงสิ่งต่างๆ ผู้รับของขวัญของเราอาจไม่ชอบไวท์ช็อกโกแลตทั้งหมด เราควรเพิ่มช็อกโกแลตปกติลงในรายการของเราเผื่อไว้ดีกว่า เนื่องจากฉันขี้เกียจมาก ฉันจะกดลูกศรขึ้นและแก้ไขคำสั่ง Bash ก่อนหน้า โชคดีที่คำสุดท้ายใน $STUFF ตัวแปรคือ "ช็อกโกแลต" ซึ่งมีความยาวเก้าอักขระ ดังนั้นฉันจะบอกให้ Bash เก็บเฉพาะส่วนนั้นโดยใช้ ${parameter:offset} . ฉันจะใช้ tee ของ -a ตั้งค่าสถานะเป็น a ต่อท้ายรายการที่มีอยู่ของฉัน:

echo "${STUFF: -9}" | tee -a {Amy,Brian,Charlie}.txt

cat {Amy,Brian,Charlie}.txt

socks
candy cane
white chocolate
chocolate
socks
candy cane
white chocolate
chocolate
socks
candy cane
white chocolate
chocolate

คุณยังสามารถ:

ทำเช่นนี้ ด้วยสิ่งนี้
รับสตริงย่อยจาก n ตัวอักษรเป็นต้นไป ${parameter:n}
รับสตริงย่อยสำหรับ x ตัวอักษรเริ่มต้นที่ n ${parameter:n:x}

ที่นั่น! ตอนนี้รายการฐานของเราเสร็จสิ้นแล้ว กินไข่เจียวกัน

การทดสอบตัวแปร

รู้ไหม มันอาจจะเป็น Eggnog แต่ฉันคิดว่าฉันเริ่มรายการให้ Amy เมื่อวานนี้และเก็บไว้ในตัวแปรที่ฉันอาจเรียกว่า amy . ลองดูว่าฉันทำ ฉันจะใช้ ${parameter:?word} การขยาย. มันจะเขียน word ไปที่ข้อผิดพลาดมาตรฐานและออกหากไม่มี amy พารามิเตอร์

echo "${amy:?no such}"

bash: amy: no such

ฉันเดาว่าไม่. บางทีอาจจะเป็นไบรอันแทน?

echo "${brian:?no such}"

Lederhosen

คุณยังสามารถ:

ทำเช่นนี้ ด้วยสิ่งนี้
แทนที่ word ถ้า parameter ไม่ได้ตั้งค่าหรือเป็นโมฆะ ${parameter:-word}
แทนที่ word ถ้า parameter ไม่ได้ตั้งค่าหรือเป็นโมฆะ ${parameter:+word}
กำหนด word เป็น parameter ถ้า parameter ไม่ได้ตั้งค่าหรือเป็นโมฆะ ${parameter:=word}

เปลี่ยนเคส

ถูกตัอง! Brian บอกว่าเขาอยากได้ lederhosen ฉันก็เลยจดบันทึกเอาไว้ นี่ค่อนข้างสำคัญ ดังนั้นฉันจะเพิ่มลงในรายการของ Brian ด้วยตัวพิมพ์ใหญ่ด้วย ${parameter^^pattern} การขยาย. pattern ส่วนหนึ่งเป็นตัวเลือก เราเขียนถึง Brian เท่านั้น ดังนั้นฉันจะใช้ >> แทน tee -a .

echo "${brian^^}" >> Brian.txt

cat Brian.txt

socks
candy cane
white chocolate
chocolate
LEDERHOSEN

คุณยังสามารถ:

ทำเช่นนี้ ด้วยสิ่งนี้
ใช้อักษรตัวแรกเป็นตัวพิมพ์ใหญ่ ${parameter^^pattern}
อักษรตัวแรกตัวพิมพ์เล็ก ${parameter,pattern}
ตัวพิมพ์เล็กทั้งหมด ${parameter,,pattern}

การขยายอาร์เรย์

คุณรู้อะไรไหม ธุรกิจรายการของขวัญทั้งหมดนี้ต้องทำงานหนัก ฉันแค่จะทำสิ่งต่าง ๆ มากมายที่ฉันเห็นที่ร้าน:

gifts=(sweater gameboy wagon pillows chestnuts hairbrush)

ฉันสามารถใช้การขยายสตริงย่อยในรูปแบบของ ${parameter:offset:length} เพื่อทำให้สิ่งนี้ง่าย ฉันจะเพิ่มสองคนแรกในรายการของเอมี่ สองคนตรงกลางของไบรอัน และสองคนสุดท้ายในรายชื่อของชาร์ลี ฉันจะใช้ printf เพื่อช่วยในการขึ้นบรรทัดใหม่

printf '%s\n' "${gifts[@]:0:2}" >> Amy.txt
printf '%s\n' "${gifts[@]:2:2}" >> Brian.txt
printf '%s\n' "${gifts[@]: -2}" >> Charlie.txt
cat Amy.txt

socks
candy cane
white chocolate
chocolate
sweater
gameboy

cat Brian.txt

socks
candy cane
white chocolate
chocolate
LEDERHOSEN
wagon
pillows

cat Charlie.txt

socks
candy cane
white chocolate
chocolate
chestnuts
hairbrush

ที่นั่น! ตอนนี้เรามีรายการของขวัญที่ปรับเปลี่ยนในแบบของคุณได้อย่างครอบคลุม ขอบคุณทุบตี! น่าเสียดายที่ไม่สามารถซื้อของให้เราได้เช่นกัน