คู่มือสำหรับผู้เริ่มต้นสู่การเขียนสคริปต์เชลล์ 2 สำหรับลูป
หากคุณต้องการสร้างความน่าเชื่อถือให้เข้าร่วมกับเราสำหรับงวดที่สองในชุดสคริปต์เชลล์ของเรา เรามีการแก้ไขเล็กน้อยการปรับปรุงบางส่วนของสคริปต์ของสัปดาห์ที่แล้วและคำแนะนำในการวนซ้ำสำหรับผู้เริ่มต้น.
สคริปต์ datecp ได้รับการตรวจสอบอีกครั้ง
ในงวดแรกของคู่มือการใช้สคริปต์เชลล์เราสร้างสคริปต์ที่คัดลอกไฟล์ไปยังไดเรกทอรีสำรองหลังจากผนวกวันที่ต่อท้ายชื่อไฟล์.
ซามูเอลดิออน - เรียลชี้ให้เห็นในความคิดเห็นว่ามีวิธีที่ดีกว่ามากในการจัดการการอ้างอิงตัวแปรของเรา.
อาร์กิวเมนต์คั่นด้วยช่องว่างในเชลล์ bash ซึ่งจะโทเค็นเมื่อมีช่องว่างในคำสั่งที่ขยายออกมา ในสคริปต์ของคุณ,
cp $ 1 $ 2. $ date_formatted
จะทำงานตามที่ตั้งใจไว้ตราบใดที่ตัวแปรที่ขยายเพิ่มไม่มีช่องว่าง หากคุณเรียกสคริปต์ของคุณด้วยวิธีนี้:datecp "ชื่อเก่าของฉัน" "ชื่อใหม่ของฉัน"
การขยายตัวจะส่งผลให้คำสั่งนี้:cp ชื่อใหม่ของฉันชื่อเก่าของฉัน the_date
ซึ่งมี 6 ข้อโต้แย้ง.ในการแก้ไขปัญหานี้อย่างถูกต้องบรรทัดสุดท้ายของสคริปต์ควรเป็น:
cp "$ 1" "$ 2 $ date_formatted"
อย่างที่คุณเห็นการเปลี่ยนบรรทัดสคริปต์ของเราจาก:
cp -iv $ 1 $ 2. $ date_formatted
ไปที่:
cp -iv“ $ 1”“ $ 2”. $ date_formatted
จะดูแลปัญหานี้เมื่อใช้สคริปต์กับไฟล์ที่มีช่องว่างในชื่อ ซามูเอลยังชี้ให้เห็นว่าเมื่อคัดลอกและวางรหัสจากเว็บไซต์นี้ (หรืออินเทอร์เน็ตทั่วไป) ต้องแน่ใจว่าได้แทนที่เครื่องหมายขีดคั่นและเครื่องหมายคำพูดที่เหมาะสมสำหรับ“ ตัวพิมพ์ที่ดีกว่า” ที่มักจะแทนที่ นอกจากนี้เราจะทำสิ่งต่างๆให้มากขึ้นเพื่อให้แน่ใจว่ารหัสของเรานั้นง่ายต่อการคัดลอกและวาง ;-)
นักวิจารณ์คนอื่น Myles Braithwaite ตัดสินใจที่จะขยายสคริปต์ของเราเพื่อให้วันที่ปรากฏก่อนนามสกุลไฟล์ ดังนั้นแทนที่จะ
tastyfile.mp3.07_14_11-12.34.56
เราจะได้สิ่งนี้:
tastyfile.07_14_11-12.34.56.mp3
ซึ่งทำให้การใช้งานสะดวกขึ้นเล็กน้อยสำหรับผู้ใช้ส่วนใหญ่ รหัสของเขามีอยู่ที่หน้า GitHub ของเขา ลองดูที่สิ่งที่เขาใช้เพื่อแยกชื่อไฟล์.
date_formatted = $ (วันที่ +% Y-% m-% d_% H. % M% S)
file_extension = $ (echo“ $ 1 "| awk -F. 'พิมพ์ $ NF')
file_name = $ (basename $ 1. $ file_extension)cp -iv $ 1 $ file_name- $ date_formatted $ file_extension
ฉันเปลี่ยนรูปแบบเล็กน้อย แต่คุณจะเห็นว่า Myles ประกาศฟังก์ชันวันที่ของเขาในบรรทัดที่ 1 ในบรรทัดที่ 2 อย่างไรก็ตามเขาใช้คำสั่ง“ echo” พร้อมอาร์กิวเมนต์แรกของสคริปต์เพื่อส่งชื่อไฟล์ เขาใช้คำสั่ง pipe เพื่อใช้เอาต์พุตนั้นและใช้เป็นอินพุตสำหรับส่วนถัดไป หลังจากไปป์ Myles เรียกใช้คำสั่ง“ awk” ซึ่งเป็นโปรแกรมการสแกนรูปแบบที่ทรงพลัง ใช้แฟล็ก -F เขาบอกคำสั่งว่าตัวละครถัดไป (หลังจากเว้นวรรค) คือสิ่งที่จะกำหนด "ตัวคั่นฟิลด์" ในกรณีนี้นั่นคือช่วงเวลา.
ตอนนี้ awk ดูไฟล์ชื่อ“ Deliciousfile.mp3” ซึ่งประกอบด้วยสองฟิลด์:“ Deliciousfile” และ“ mp3” สุดท้ายเขาก็ใช้
'พิมพ์ $ NF'
เพื่อแสดงฟิลด์สุดท้าย ในกรณีที่ไฟล์ของคุณมีหลายช่วงเวลา - ทำให้ awk เห็นหลาย ๆ ฟิลด์ - มันจะแสดงเฉพาะช่วงสุดท้ายซึ่งเป็นนามสกุลไฟล์.
ในบรรทัดที่ 3 เขาสร้างตัวแปรใหม่สำหรับชื่อไฟล์และใช้คำสั่ง "basename" เพื่ออ้างอิงทุกอย่างใน $ 1 ยกเว้น นามสกุลไฟล์ สิ่งนี้ทำได้โดยใช้ basename และให้ $ 1 เป็นอาร์กิวเมนต์ของมันจากนั้นเพิ่มช่องว่างและนามสกุลไฟล์ นามสกุลไฟล์จะถูกเพิ่มเข้ามาโดยอัตโนมัติเนื่องจากตัวแปรที่อ้างอิงบรรทัด 2 สิ่งนี้จะทำ
tastyfile.mp3
และเปลี่ยนเป็น
tastyfile
จากนั้นในบรรทัดสุดท้าย Myles รวบรวมคำสั่งที่จะส่งออกทุกอย่างตามลำดับ โปรดทราบว่าไม่มีการอ้างอิงถึง $ 2 ซึ่งเป็นอาร์กิวเมนต์ที่สองสำหรับสคริปต์ สคริปต์เฉพาะนี้จะคัดลอกไฟล์ดังกล่าวไปยังไดเรกทอรีปัจจุบันของคุณแทน ทำได้ดีมากกับซามูเอลและไมลส์!
กำลังเรียกใช้สคริปต์และ $ PATH
นอกจากนี้เรายังพูดถึงในบทความพื้นฐานของเราว่าสคริปต์ไม่ได้รับอนุญาตให้อ้างอิงเป็นคำสั่งโดยค่าเริ่มต้น นั่นคือคุณต้องชี้ไปที่เส้นทางของสคริปต์เพื่อเรียกใช้:
./ script
~ / bin / script
แต่ด้วยการวางสคริปต์ของคุณใน ~ / bin / คุณสามารถพิมพ์ชื่อของพวกเขาจากที่ใดก็ได้เพื่อให้พวกเขาทำงาน.
ผู้แสดงความคิดเห็นใช้เวลาในการพิจารณาว่าเรื่องนี้เหมาะสมอย่างไรเนื่องจากไม่มีดิสทริบิวเตอร์ distro รุ่นใหม่ที่สร้างไดเรกทอรีดังกล่าวตามค่าเริ่มต้น นอกจากนี้ยังไม่มีใครเพิ่มลงในตัวแปร $ PATH โดยค่าเริ่มต้นซึ่งเป็นสิ่งที่จำเป็นเพื่อให้สคริปต์ทำงานเหมือนคำสั่ง ฉันงงนิดหน่อยเพราะหลังจากตรวจสอบตัวแปร $ PATH ผู้แสดงความเห็นถูกต้อง แต่สคริปต์การโทรยังใช้งานได้สำหรับฉัน ฉันค้นพบสาเหตุ: ดิสทริบิวเตอร์ distros รุ่นใหม่หลายคนสร้างไฟล์พิเศษในโฮมไดเร็กตอรี่ของผู้ใช้ -. profile.
ไฟล์นี้ถูกอ่านโดย bash (ยกเว้นว่า. bash_profile ปรากฏอยู่ในโฮมไดเร็กตอรี่ของผู้ใช้) และที่ด้านล่างมีส่วนที่เพิ่ม ~ / bin / โฟลเดอร์ไปยังตัวแปร $ PATH หากมีอยู่ ดังนั้นความลึกลับนั้นจึงถูกลบล้างไป สำหรับซีรีส์ที่เหลือฉันจะวางสคริปต์ต่อไปในไดเรกทอรี ~ / bin / เพราะเป็นสคริปต์ผู้ใช้และควรจะสามารถเรียกใช้โดยผู้ใช้ และดูเหมือนว่าเราไม่จำเป็นต้องยุ่งกับตัวแปร $ PATH ด้วยมือเพื่อให้สิ่งต่าง ๆ ทำงานได้.
การทำซ้ำคำสั่งด้วยลูป
มาเป็นหนึ่งในเครื่องมือที่มีประโยชน์ที่สุดในคลังแสงที่เกินบรรยายสำหรับจัดการกับงานซ้ำ ๆ : ลูป วันนี้เราจะมาพูดถึงลูป "สำหรับ".
โครงร่างพื้นฐานของ for-loop เป็นดังนี้:
เพื่อความหลากหลายใน LIST; ทำ
Command1
Command2
...
CommandN
เสร็จแล้ว
ตัวแปรสามารถเป็นตัวแปรใดก็ได้แม้ว่าโดยทั่วไปแล้วตัวพิมพ์เล็ก "i" จะถูกใช้โดยการประชุม รายการคือรายการของรายการ; คุณสามารถระบุหลายรายการ (คั่นด้วยช่องว่าง) ชี้ไปที่ไฟล์ข้อความภายนอกหรือใช้เครื่องหมายดอกจัน (*) เพื่อแสดงไฟล์ใด ๆ ในไดเรกทอรีปัจจุบัน คำสั่งที่แสดงรายการจะถูกเยื้องโดยการประชุมดังนั้นจึงง่ายต่อการดูการซ้อน - การวนซ้ำในการวนซ้ำ (เพื่อให้คุณสามารถวนซ้ำในขณะที่คุณวนซ้ำ).
เนื่องจากรายการใช้ช่องว่างเป็นตัวคั่น - นั่นคือช่องว่างหมายถึงการย้ายไปยังรายการถัดไปในรายการ - ไฟล์ที่มีช่องว่างในชื่อจึงไม่เป็นมิตร ตอนนี้มาทำงานกับไฟล์ที่ไม่มีช่องว่างมาเริ่มด้วยสคริปต์ง่าย ๆ เพื่อแสดงชื่อไฟล์ในไดเรกทอรีปัจจุบัน สร้างสคริปต์ใหม่ใน ~ / bin / โฟลเดอร์ชื่อ“ loopscript” หากคุณจำไม่ได้ว่าจะทำอย่างไร (รวมถึงการทำเครื่องหมายว่าสามารถปฏิบัติการได้และเพิ่มแฮ็กแฮ็ก) อ้างอิงถึงบทความพื้นฐานการเขียนสคริปต์ทุบตีของเรา.
ในนั้นใส่รหัสต่อไปนี้:
สำหรับฉันใน item1 item2 item3 item4 item5 item6; ทำ
echo“ $ i”
เสร็จแล้ว
เมื่อคุณเรียกใช้สคริปต์คุณควรได้รับรายการเหล่านั้นเป็นผลลัพธ์.
ค่อนข้างง่ายใช่มั้ย เรามาดูกันว่าจะเกิดอะไรขึ้นถ้าเราเปลี่ยนสิ่งต่าง ๆ เล็กน้อย เปลี่ยนสคริปต์ของคุณเพื่อให้มันบอกว่าสิ่งนี้:
สำหรับฉันใน *; ทำ
echo“ $ i”
เสร็จแล้ว
เมื่อคุณเรียกใช้สคริปต์นี้ในโฟลเดอร์คุณควรได้รับรายชื่อของไฟล์ที่มันเป็นเอาท์พุท.
ทีนี้มาเปลี่ยนคำสั่ง echo ให้เป็นประโยชน์มากขึ้น - พูดคำสั่ง zip กล่าวคือเราจะเพิ่มไฟล์ลงในไฟล์เก็บถาวร และขอขัดแย้งในการผสมกัน!
สำหรับฉันใน $ @; ทำ
ไฟล์ zip“ $ i”
เสร็จแล้ว
มีอะไรใหม่! “ $ @” เป็นทางลัดสำหรับ“ $ 1 $ 2 $ 3 … $ n” นั่นคือรายการทั้งหมดของอาร์กิวเมนต์ทั้งหมดที่คุณระบุ ตอนนี้ดูว่าเกิดอะไรขึ้นเมื่อฉันเรียกใช้สคริปต์ด้วยไฟล์อินพุตหลายไฟล์.
คุณสามารถดูไฟล์ที่อยู่ในโฟลเดอร์ของฉัน ฉันรันคำสั่งด้วยหกอาร์กิวเมนต์และแต่ละไฟล์ถูกเพิ่มลงในไฟล์ซิปที่ชื่อ“ archive.zip” ง่ายถูกต้อง?
สำหรับลูปนั้นวิเศษมาก ตอนนี้คุณสามารถเรียกใช้ฟังก์ชันแบตช์ในรายการไฟล์ ตัวอย่างเช่นคุณสามารถคัดลอกอาร์กิวเมนต์ทั้งหมดของสคริปต์ของคุณลงในไฟล์บีบอัดซิปย้ายต้นฉบับไปยังโฟลเดอร์อื่นและคัดลอกไฟล์ zip นั้นไปยังคอมพิวเตอร์ระยะไกลโดยอัตโนมัติ หากคุณตั้งค่าไฟล์คีย์ด้วย SSH คุณไม่จำเป็นต้องป้อนรหัสผ่านและคุณสามารถบอกให้สคริปต์ลบไฟล์ zip หลังจากอัปโหลด!
การใช้ for-loops ทำให้การดำเนินการต่างๆเป็นไปอย่างง่ายดายสำหรับไฟล์ทั้งหมดในไดเรกทอรี คุณสามารถสแต็กคำสั่งที่หลากหลายเข้าด้วยกันและใช้อาร์กิวเมนต์ได้ง่ายมากในการสร้างและรายการแบบทันทีและนี่เป็นเพียงส่วนเล็ก ๆ ของภูเขาน้ำแข็ง.
ทุบตี Scripters คุณมีข้อเสนอแนะใด ๆ ? คุณสร้างสคริปต์ที่มีประโยชน์ที่ใช้ลูปหรือไม่? ต้องการแบ่งปันความคิดของคุณในซีรี่ส์หรือไม่ แสดงความคิดเห็นและช่วยมือใหม่อื่น ๆ ในการเขียนสคริปต์!