เหตุผลว่าทำไม
tac file | grep foo | head -n 1
ไม่หยุดที่คู่แรกเป็นเพราะการบัฟเฟอร์
โดยปกติแล้วhead -n 1
จะออกหลังจากอ่านบรรทัด ดังนั้นgrep
ควรรับ SIGPIPE และออกเช่นกันทันทีที่มันเขียนบรรทัดที่สอง
แต่สิ่งที่เกิดขึ้นก็คือเนื่องจากเอาต์พุตของมันไม่ได้ไปที่เทอร์มินัลgrep
บัฟเฟอร์มัน นั่นคือมันไม่ได้เขียนจนกว่ามันจะสะสมเพียงพอ (4096 bytes ในการทดสอบของฉันกับ grep GNU)
สิ่งที่หมายถึงคือgrep
จะไม่ออกก่อนที่จะเขียนข้อมูล 8192 ไบต์ดังนั้นอาจมีบางบรรทัด
ด้วย GNU grep
คุณสามารถทำให้มันออกได้เร็วขึ้นโดยใช้--line-buffered
ซึ่งบอกให้เขียนบรรทัดทันทีที่พบโดยไม่คำนึงว่าจะไปที่เทอร์มินัลหรือไม่ ดังนั้นgrep
จะออกเมื่อพบบรรทัดที่สอง
แต่ด้วย GNU grep
คุณสามารถใช้-m 1
แทนได้เช่น @terdon แสดงซึ่งดีกว่าเมื่อออกจากการแข่งขันนัดแรก
หากคุณgrep
ไม่ใช่ GNU grep
คุณสามารถใช้sed
หรือawk
แทน แต่tac
เป็นคำสั่ง GNU ผมสงสัยคุณจะพบว่าระบบที่มีtac
ที่grep
ไม่ได้เป็น grep
GNU
tac file | sed "/$pattern/!d;q" # BRE
tac file | P=$pattern awk '$0 ~ ENVIRON["P"] {print; exit}' # ERE
บางระบบต้องtail -r
ทำสิ่งเดียวกันกับที่ GNU tac
ทำ
โปรดทราบว่าสำหรับไฟล์ปกติ (หาได้) tac
และtail -r
มีประสิทธิภาพเพราะอ่านไฟล์ย้อนหลังพวกเขาไม่เพียงแค่อ่านไฟล์ในหน่วยความจำอย่างเต็มที่ก่อนที่จะพิมพ์ย้อนกลับ (เป็นวิธีการที่@ slmหรือtac
ไฟล์ที่ไม่ใช่ปกติ) .
ในระบบที่ค่าtac
มิได้tail -r
ที่มีตัวเลือกเดียวที่จะดำเนินการย้อนหลังอ่านด้วยมือกับการเขียนโปรแกรมภาษาเช่นperl
หรือการใช้งาน:
grep -e "$pattern" file | tail -n1
หรือ:
sed "/$pattern/h;$!d;g" file
แต่นั่นหมายถึงการค้นหาการแข่งขันทั้งหมดและพิมพ์ครั้งสุดท้ายเท่านั้น