การเปลี่ยน IFS ชั่วคราวก่อน a for loop [ซ้ำ]
ฉันรู้ว่าการSHELLอนุญาตให้กำหนดตัวแปรเกิดขึ้นทันทีก่อนคำสั่งซึ่งได้IFS=":" read a b c d <<< "$here_string"ผล ...
สิ่งที่ฉันสงสัยคือการมอบหมายงานดังกล่าวไม่ได้ผลเมื่อทำด้วยคำสั่งประกอบเช่นลูป? ฉันลองทำบางอย่างเช่นIFS=":" for i in $PATH; do echo $i; doneแต่ผลลัพธ์เกิดข้อผิดพลาดทางไวยากรณ์ ฉันสามารถทำสิ่งที่ชอบได้เสมอoldIFS="$IFS"; IFS=":"; for....; IFS="$oldIFS"แต่ฉันต้องการทราบว่ามีวิธีใดบ้างที่ฉันสามารถทำให้การมอบหมายแบบอินไลน์ทำงานสำหรับคำสั่งผสมเช่นforลูปได้หรือไม่?
คำตอบ
forเป็นคำสงวนและเป็นไปตามกฎพิเศษ :
คำต่อไปนี้ให้ถือเป็นคำสงวน:
! {} case do elif else esac fi for if in then until while
การรับรู้นี้จะเกิดขึ้นก็ต่อเมื่อไม่มีการยกตัวอักษรใด ๆ และเมื่อใช้คำเป็น:
คำแรกของคำสั่ง
ครั้งแรกที่คำต่อไปนี้อย่างใดอย่างหนึ่งของคำลิขสิทธิ์อื่น ๆ นอกเหนือจากกรณี , สำหรับหรือใน
คำที่สามในคำสั่ง case (เฉพาะในเท่านั้นที่ใช้ได้ในกรณีนี้)
คำที่สามในคำสั่ง for (เฉพาะในและdoเท่านั้นที่ใช้ได้ในกรณีนี้)
ถ้าคุณพยายาม
IFS=":" for i in $PATH; do echo $i; done
ตามกฎข้างต้นนั่นไม่ใช่การforวนซ้ำเนื่องจากคีย์เวิร์ดไม่ใช่คำแรกของคำสั่ง แต่ความตั้งใจของคุณสามารถทำได้ด้วย
IFS=: printf '%s\n' $PATH
$PATHได้รับการแบ่งคำ:ตามที่คาดไว้และแต่ละคำที่ได้จะถูกพิมพ์printfตามด้วยขึ้นบรรทัดใหม่
คุณอาจคุ้นเคยกับแนวทางที่ถูกต้องนี้:
while IFS= read -r line; do
whileเป็นคำแรกของคำสั่งและการIFSกำหนดใช้กับreadดังนั้นทุกอย่างก็โอเค