มันค่อนข้างง่ายที่จะอ่านเนื้อหาของไฟล์ข้อความ Linux ตามบรรทัดในสคริปต์เชลล์ - ตราบใดที่คุณจัดการกับ gotchas ที่ละเอียดอ่อน นี่คือวิธีการทำวิธีที่ปลอดภัย
ไฟล์ข้อความและสำนวน
ภาษาการเขียนโปรแกรมแต่ละภาษามีชุดสำนวน นี่คือมาตรฐานที่ไม่มีการจีบเพื่อให้บรรลุชุดงานทั่วไป พวกเขาเป็นวิธีเบื้องต้นหรือวิธีเริ่มต้นในการใช้หนึ่งในคุณสมบัติของภาษาที่โปรแกรมเมอร์กำลังทำงานกับ พวกเขากลายเป็นส่วนหนึ่งของชุดเครื่องมือของโปรแกรมเมอร์ของพิมพ์เขียวจิต
การกระทำเช่นการอ่านข้อมูลจากไฟล์ทำงานกับลูปและการสลับค่าของตัวแปรสองตัวเป็นตัวอย่างที่ดี โปรแกรมเมอร์จะรู้อย่างน้อยหนึ่งวิธีในการบรรลุเป้าหมายในแฟชั่นทั่วไปหรือวานิลลา บางทีอาจจะพอเพียงสำหรับความต้องการในมือ หรือบางทีพวกเขาอาจจะตกแต่งโค้ดเพื่อให้มีประสิทธิภาพมากขึ้นหรือใช้ได้กับโซลูชันเฉพาะที่พวกเขากำลังพัฒนา แต่การมีสำนวนอาคารบล็อกที่ปลายนิ้วของพวกเขาเป็นจุดเริ่มต้นที่ยอดเยี่ยม
การรู้และการเข้าใจสำนวนในภาษาเดียวทำให้ง่ายต่อการรับภาษาการเขียนโปรแกรมใหม่เช่นกัน การรู้ว่าสิ่งต่าง ๆ ถูกสร้างขึ้นในภาษาเดียวและมองหาสิ่งที่เทียบเท่า - หรือสิ่งที่ใกล้เคียงที่สุดในภาษาอื่นเป็นวิธีที่ดีในการชื่นชมความคล้ายคลึงกันและความแตกต่างระหว่างภาษาการเขียนโปรแกรมที่คุณรู้จักและคนที่คุณกำลังเรียนรู้
อ่านบรรทัดจากไฟล์: หนึ่งซับ
ในทุบตีคุณสามารถใช้
ในขณะที่
ลูปบนบรรทัดคำสั่งเพื่ออ่านข้อความแต่ละบรรทัดจากไฟล์และทำอะไรกับมัน ไฟล์ข้อความของเราเรียกว่า "Data.txt" มันถือรายการของเดือนของปี
มกราคม กุมภาพันธ์ มีนาคม . . ตุลาคม พฤศจิกายน ธันวาคม
ไลเนอร์เดียวที่เรียบง่ายของเราคือ:
ในขณะที่อ่านบรรทัด; ทำสาย echo $; เสร็จแล้ว & lt; data.txt
NS
ในขณะที่
ลูปอ่านบรรทัดจากไฟล์และการไหลของโปรแกรมเล็ก ๆ ที่ส่งผ่านไปยังร่างกายของลูป NS
ก้อง
คำสั่งเขียนบรรทัดของข้อความในหน้าต่างเทอร์มินัล ความพยายามในการอ่านล้มเหลวเมื่อไม่มีการอ่านบรรทัดเพิ่มเติมและการวนซ้ำจะเสร็จสิ้น
หนึ่งเคล็ดลับที่เรียบร้อยคือความสามารถ เพื่อเปลี่ยนเส้นทางไฟล์เป็นลูป . ในภาษาการเขียนโปรแกรมอื่น ๆ คุณต้องเปิดไฟล์อ่านจากนั้นและปิดอีกครั้งเมื่อคุณทำเสร็จ ด้วยทุบตีคุณสามารถใช้การเปลี่ยนเส้นทางไฟล์และปล่อยให้เชลล์จัดการกับสิ่งของระดับต่ำทั้งหมดสำหรับคุณ
แน่นอนว่าหนึ่งซับนี้ไม่มีประโยชน์อย่างมาก Linux ให้บริการแล้ว
แมว
คำสั่งซึ่งทำอย่างนั้นสำหรับเรา เราได้สร้างวิธีที่คดเคี้ยวมานานเพื่อแทนที่คำสั่งสามตัวอักษร แต่มันแสดงให้เห็นถึงหลักการของการอ่านจากไฟล์อย่างเห็นได้ชัด
ทำงานได้ดีพอถึงจุด สมมติว่าเรามีไฟล์ข้อความอื่นที่มีชื่อของเดือน ในไฟล์นี้ลำดับ Escape สำหรับอักขระ Newline ได้รับการผนวกเข้ากับแต่ละบรรทัด เราจะเรียกว่า "Data2.txt"
มกราคม \ n กุมภาพันธ์ \ n มีนาคม \ n . . ตุลาคม \ n พฤศจิกายน \ n ธันวาคม \ n
ลองใช้ Liner One-Liner ของเราในไฟล์ใหม่ของเรา
ในขณะที่อ่านบรรทัด; ทำสาย echo $; เสร็จแล้ว & lt; data2.txt
ตัวละคร Escape Backslash "
\
"ถูกทิ้ง ผลลัพธ์คือ "N" ได้รับการผนวกเข้ากับแต่ละบรรทัด ทุบตีกำลังตีความแบ็กสแลชเป็นจุดเริ่มต้นของ
ลำดับการหลบหนี
. บ่อยครั้งที่เราไม่ต้องการทุบตีเพื่อตีความสิ่งที่มันกำลังอ่าน สามารถสะดวกในการอ่านบรรทัดในลำดับ Escape-backslet-backslet และทั้งหมดและเลือกสิ่งที่จะแยกวิเคราะห์หรือแทนที่ตัวเองภายในรหัสของคุณเอง
หากเราต้องการทำการประมวลผลที่มีความหมายหรือการแยกวิเคราะห์ในบรรทัดข้อความเราจะต้องใช้สคริปต์
อ่านบรรทัดจากไฟล์ที่มีสคริปต์
นี่คือสคริปต์ของเรา มันเรียกว่า "script1.sh"
#! / bin / bash
เคาน์เตอร์ = 0
ในขณะที่ IFS = '' อ่าน -r LinefromFile [116 ] || [[ -n " $ {LinefromFile} " ] ] ทำ
(( เคาน์เตอร์ ++ ))
ก้อง "การเข้าถึงเส้น $ เคาน์เตอร์ : $ {LinefromFile} " [9 ]
ทำ & lt; " $ 1 "
เราตั้งค่าตัวแปรที่เรียกว่า
เคาน์เตอร์
เป็นศูนย์จากนั้นเรากำหนดของเรา
ในขณะที่
ลูป.
คำสั่งแรกในขณะที่บรรทัดคือ
IFS = ''
.
ถ้า
ย่อมาจากตัวคั่นสนามภายใน มันถือค่าที่ Bash ใช้เพื่อระบุขอบเขตของ Word ตามค่าเริ่มต้นคำสั่งอ่านแถบปิดช่องว่างชั้นนำและต่อท้าย หากเราต้องการอ่านบรรทัดจากไฟล์ตามที่เป็นอยู่เราต้องตั้งค่า
ถ้า
เป็นสตริงว่างเปล่า
เราสามารถตั้งค่านี้หนึ่งครั้งนอกลูปเช่นเดียวกับที่เรากำลังตั้งค่าของ
เคาน์เตอร์
. แต่ด้วยสคริปต์ที่ซับซ้อนมากขึ้นโดยเฉพาะผู้ที่มีฟังก์ชั่นที่ผู้ใช้กำหนดจำนวนมากในนั้นเป็นไปได้ว่า
ถ้า
สามารถตั้งค่าให้กับค่าต่าง ๆ ที่อื่นในสคริปต์ ทำให้มั่นใจว่า
ถ้า
ถูกตั้งค่าเป็นสตริงว่างในแต่ละครั้ง
ในขณะที่
วนซ้ำการรับประกันว่าเรารู้ว่าพฤติกรรมของมันคืออะไร
เราจะอ่านบรรทัดของข้อความลงในตัวแปรที่เรียกว่า
linefromfile
. เรากำลังใช้
-NS
(อ่านแบ็กสแลชเป็นอักขระปกติ) ตัวเลือกเพื่อละเว้นแบ็กสแลช พวกเขาจะได้รับการปฏิบัติเช่นเดียวกับตัวละครอื่น ๆ และจะไม่ได้รับการรักษาพิเศษใด ๆ
มีสองเงื่อนไขที่จะตอบสนอง
ในขณะที่
วนซ้ำและอนุญาตให้ประมวลผลข้อความที่ร่างกายของลูป:
-
อ่าน -r linefromfile: เมื่ออ่านบรรทัดข้อความสำเร็จจากไฟล์อ่านคำสั่งส่งสัญญาณความสำเร็จไปที่ในขณะที่, และในขณะที่ลูปผ่านการดำเนินการไหลไปยังร่างกายของลูป โปรดทราบว่าอ่านคำสั่งจำเป็นต้องดู อักขระขึ้นบรรทัดใหม่ ในตอนท้ายของบรรทัดข้อความเพื่อพิจารณาการอ่านที่ประสบความสำเร็จ หากไฟล์ไม่ได้เป็น posix ไฟล์ข้อความที่สอดคล้องกับ บรรทัดสุดท้ายอาจไม่รวมอักขระใหม่ . หากว่าอ่านคำสั่งเห็น จุดสิ้นสุดของเครื่องหมายไฟล์ (EOF) ก่อนที่บรรทัดจะถูกยกเลิกโดยบรรทัดใหม่มันจะ ไม่ ถือว่าเป็นการอ่านที่ประสบความสำเร็จ หากสิ่งนั้นเกิดขึ้นบรรทัดสุดท้ายของข้อความจะไม่ถูกส่งผ่านไปยังร่างกายของลูปและจะไม่ถูกประมวลผล -
[-N "$ {LINEFROMFILE}"]: เราต้องทำงานพิเศษเพื่อจัดการไฟล์ที่ใช้งานร่วมกันได้ที่ไม่ใช่ POSIX การเปรียบเทียบนี้ตรวจสอบข้อความที่อ่านจากไฟล์ หากไม่สิ้นสุดด้วยอักขระใหม่การเปรียบเทียบนี้จะยังคงกลับสู่ความสำเร็จในขณะที่ลูป. สิ่งนี้ทำให้มั่นใจได้ว่าชิ้นส่วนต่อท้ายบรรทัดใด ๆ จะถูกประมวลผลโดยร่างกายของลูป
ข้อนี้สองข้อแยกจากกันโดยผู้ประกอบการหรือตรรกะ "
||
"แล้วถ้า
ทั้ง
ประโยคผลตอบแทนที่ประสบความสำเร็จข้อความที่ดึงมาจะถูกประมวลผลโดยร่างกายของลูปไม่ว่าจะมีอักขระใหม่หรือไม่
ในร่างกายของลูปของเราเรากำลังเพิ่มขึ้น
เคาน์เตอร์
ตัวแปรโดยหนึ่งและใช้
ก้อง
ในการส่งเอาต์พุตไปยังหน้าต่างเทอร์มินัล หมายเลขบรรทัดและข้อความของแต่ละบรรทัดจะปรากฏขึ้น
เรายังสามารถใช้เคล็ดลับการเปลี่ยนเส้นทางของเราเพื่อเปลี่ยนเส้นทางไฟล์เป็นลูป ในกรณีนี้เรากำลังเปลี่ยนเส้นทาง $ 1 ตัวแปรที่เก็บชื่อของพารามิเตอร์บรรทัดคำสั่งแรกที่ส่งผ่านไปยังสคริปต์ การใช้เคล็ดลับนี้เราสามารถส่งผ่านชื่อไฟล์ข้อมูลที่เราต้องการให้สคริปต์ทำงานได้อย่างง่ายดาย
คัดลอกและวางสคริปต์ลงในโปรแกรมแก้ไขและบันทึกด้วยชื่อไฟล์ "Script1.sh" ใช้
chmod
สั่งการ
เพื่อให้สามารถเรียกใช้งานได้
.
chmod + x script1.sh
เรามาดูกันว่าสคริปต์ของเราทำอะไรของไฟล์ข้อความ Data2.txt และแบ็กสแลชที่มีอยู่ภายใน
./ Script1.sh Data2.txt
ตัวละครทุกตัวในบรรทัดจะแสดงคำต่อคำ แบ็กสแลชไม่ได้ตีความว่าเป็นอักขระหลบหนี พวกเขาพิมพ์เป็นตัวละครปกติ
ผ่านบรรทัดไปยังฟังก์ชั่น
เรายังคงเพิ่งสะท้อนข้อความไปที่หน้าจอ ในสถานการณ์การเขียนโปรแกรมในโลกแห่งความเป็นจริงเราอาจจะทำสิ่งที่น่าสนใจยิ่งขึ้นด้วยบรรทัดข้อความ ในกรณีส่วนใหญ่มันเป็นแนวปฏิบัติการเขียนโปรแกรมที่ดีในการจัดการการประมวลผลบรรทัดต่อไปในฟังก์ชั่นอื่น
นี่คือวิธีที่เราสามารถทำได้ นี่คือ "script2.sh"
เรากำหนดของเรา
เคาน์เตอร์
ตัวแปรเหมือนก่อนและจากนั้นเรากำหนดฟังก์ชั่นที่เรียกว่า
process_line ()
. คำจำกัดความของฟังก์ชั่นจะต้องปรากฏขึ้น
ก่อน
ฟังก์ชั่นถูกเรียกครั้งแรกในสคริปต์
ฟังก์ชั่นของเราจะถูกส่งผ่านบรรทัดข้อความที่อ่านใหม่ในการวนซ้ำแต่ละครั้งของ
ในขณะที่
ลูป. เราสามารถเข้าถึงค่านั้นภายในฟังก์ชั่นโดยใช้
$ 1
ตัวแปร. หากมีตัวแปรสองตัวส่งผ่านไปยังฟังก์ชั่นเราสามารถเข้าถึงค่าเหล่านั้นโดยใช้
$ 1
และ
$ 2
และอื่น ๆ สำหรับตัวแปรเพิ่มเติม
w
ผู้ร้าย
วนซ้ำส่วนใหญ่เหมือนกัน มีเพียงหนึ่งการเปลี่ยนแปลงภายในร่างกายของลูป NS
ก้อง
บรรทัดถูกแทนที่ด้วยการโทรไปที่
process_line ()
การทำงาน. โปรดทราบว่าคุณไม่จำเป็นต้องใช้วงเล็บ "()" ในชื่อของฟังก์ชั่นเมื่อคุณโทรมา
ชื่อของตัวแปรที่ถือบรรทัดของข้อความ
linefromfile
ถูกห่อด้วยเครื่องหมายใบเสนอราคาเมื่อส่งต่อไปยังฟังก์ชั่น เหมาะสำหรับเส้นที่มีช่องว่างในนั้น หากไม่มีเครื่องหมายคำพูดคำแรกจะถือว่าเป็น
$ 1
โดยฟังก์ชั่นคำที่สองถือว่าเป็น
$ 2
และอื่น ๆ การใช้เครื่องหมายใบเสนอราคาช่วยให้มั่นใจได้ว่ามีการจัดการบรรทัดทั้งหมดของข้อความทั้งหมดโดยสิ้นเชิงเช่นเดียวกับ
$ 1
. โปรดทราบว่านี่คือ
ไม่
เหมือน
$ 1
ที่เก็บไฟล์ข้อมูลเดียวกันที่ส่งผ่านไปยังสคริปต์
เพราะ
เคาน์เตอร์
ได้รับการประกาศในเนื้อหาหลักของสคริปต์และไม่อยู่ในฟังก์ชั่นมันสามารถอ้างอิงภายใน
process_line ()
การทำงาน.
คัดลอกหรือพิมพ์สคริปต์ด้านบนลงในโปรแกรมแก้ไขและบันทึกด้วยชื่อไฟล์ "script2.sh" ทำให้มันสามารถทำงานได้ด้วย
chmod
:
chmod + x script2.sh
ตอนนี้เราสามารถเรียกใช้และส่งผ่านในไฟล์ข้อมูลใหม่ "Data3.txt" นี่มีรายการของเดือนในนั้นและหนึ่งบรรทัดที่มีหลายคำอยู่กับมัน
มกราคม กุมภาพันธ์ มีนาคม . . ตุลาคม ข้อความพฤศจิกายน \ N More "ในตอนท้ายของบรรทัด" ธันวาคม
คำสั่งของเราคือ:
./ Script2.sh Data3.txt
บรรทัดที่อ่านจากไฟล์และส่งผ่านทีละหนึ่งไปยัง
process_line ()
การทำงาน. ทุกสายจะแสดงอย่างถูกต้องรวมถึงคี่ที่มี backspace เครื่องหมายคำพูดและหลายคำในนั้น
บล็อกอาคารมีประโยชน์
มีรถไฟแห่งความคิดที่บอกว่าสำนวนต้องมีบางสิ่งที่ไม่เหมือนใครในภาษานั้น นั่นไม่ใช่ความเชื่อที่ฉันสมัครสมาชิก สิ่งที่สำคัญคือการใช้ภาษาที่ดีจำได้ง่ายและให้วิธีที่เชื่อถือได้และแข็งแกร่งในการใช้งานฟังก์ชั่นบางอย่างในรหัสของคุณ