ทำไมคุณไม่อ่านบรรทัดที่มีเครื่องหมาย“ for” ใน bash?


7

ฉันอ่านว่าการใช้ "สำหรับ" ไม่ใช่วิธีที่ดีในการอ่านบรรทัดในการทุบตี หลายคนบอกว่านี่เป็นสิ่งที่ซุ่มซ่ามและไม่มีประสิทธิภาพและล้มเหลวในหลาย ๆ กรณี

ฉันต้องการทราบว่าวิธีที่ดีที่สุดในการอ่านบรรทัดเป็นทุบตีคืออะไร ขอบคุณ

ตัวอย่างเช่น:

$ for i in $(<afile); do echo "$i"; done

1
คุณมีตัวอย่างของสคริปต์ทุบตีที่คุณเขียนโดยใช้ "สำหรับ" หรือไม่?
L2G

ตัวอย่างเช่น: $ for i ใน $ (<afile); ทำเสียงสะท้อน "$ i"; เสร็จแล้ว
Kyrol

คำตอบ:


17

คุณกำลังพูดถึงfor line in $(cat file); doและโครงสร้างที่คล้ายกัน นี่คือ:

  • ไม่มีประสิทธิภาพเพราะทุบตีต้องวางไข่ subshell และดำเนินการcatอ่านcatออก - ไฟล์ทั้งหมด - ลงในหน่วยความจำแยกมัน (ซึ่งเป็นส่วนที่ช้าที่สุด ) เท่านั้นแล้ววนซ้ำข้อมูลทั้งหมด
  • ไม่น่าเชื่อถือเพราะทุบตีทำการแยกคำข้อมูล - ไม่เพียง แต่จะแยกตัวอักษรขึ้นบรรทัดใหม่ แต่ยังอยู่ในสิ่งใดใน $ IFS (ช่องว่างแท็บ ... )

(ถ้าคุณใช้$(<...)แทนคุณ$(cat ...)จะประหยัดสองมิลลิวินาทีบน Linux แต่ข้อเสียอื่น ๆ ทั้งหมดยังคงอยู่)

ตัวเลือกที่ดีกว่าคือการใช้readในการwhileวนซ้ำ:

while read -r line; do
    echo "Input: $line"
done < myfile.txt

หรือจากโปรแกรม:

cat file1 file2 file3 |
while read -r line; do
    echo "Input: $line"
done

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

หากคุณพยายามทำงานกับผลลัพธ์ของfindคุณควรใช้รูปแบบเดียวกัน:

find . -name "foo" -type f -print0 | while read -r -d '' file; do
    echo "File: $file"
done

ดูสิ่งนี้ด้วย:


คำตอบที่ดีมาก! คุณแสดงให้ฉันเห็นสิ่งที่ฉันต้องการเข้าใจ! ขอบคุณ!
Kyrol
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.