เมื่อแฟ้มใส่เป็นseekable (เช่นการอ่านจากแฟ้มปกติ) หรือยกเลิก seekable (เช่นการอ่านจากท่อ) sed
(และสาธารณูปโภคมาตรฐานอื่น ๆ ) จะทำงานแตกต่างกัน (อ่านINPUT FILES
ส่วนในการเชื่อมโยงนี้ )
อ้างอิงจากเอกสาร:
เมื่อยูทิลิตี้มาตรฐานอ่านไฟล์อินพุตที่ค้นหาได้และสิ้นสุดลงโดยไม่มีข้อผิดพลาดก่อนที่จะถึงจุดสิ้นสุดไฟล์ยูทิลิตี้จะต้องตรวจสอบให้แน่ใจว่าไฟล์ออฟเซ็ตในคำอธิบายไฟล์ที่เปิดอยู่ในตำแหน่งที่เหมาะสม
ดังนั้นใน:
(sed '/y/ q'; echo aaa; cat) < test
sed
ดำเนินการq
คำสั่ง uit ก่อนถึง EOF ดังนั้นจึงปล่อยให้ออฟเซ็ตไฟล์ที่จุดเริ่มต้นของzzz
บรรทัดดังนั้นcat
สามารถพิมพ์บรรทัดที่เหลือต่อไปได้ (GNU sed ไม่สอดคล้องกับ POSIX ในบางเงื่อนไขดูด้านล่าง)
และดำเนินการต่อจากเอกสาร:
สำหรับไฟล์ที่ไม่สามารถค้นหาได้สถานะของไฟล์ออฟเซ็ตในคำอธิบายไฟล์ที่เปิดสำหรับไฟล์นั้นจะไม่ได้รับการระบุ
ในกรณีนี้พฤติกรรมจะไม่ได้รับการระบุ เครื่องมือมาตรฐานส่วนใหญ่รวมถึงsed
จะใช้อินพุตให้มากที่สุด มันอ่านผ่านyyy
สายและq
uit cat
โดยไม่ต้องคืนค่าการชดเชยแฟ้มดังนั้นไม่มีอะไรเหลือสำหรับ
GNU sed
ไม่สอดคล้องกับมาตรฐานขึ้นอยู่กับการใช้ stdio ของระบบและรุ่น glibc:
$ (gsed '/y/ q'; echo aaa; cat) < test
xxx
yyy
aaa
ผลที่ได้รับมาจาก Mac OSX 10.11.6 เครื่องเสมือน Centos 7.2 - glibc 2.17, Ubuntu 14.04 - glibc 2.19 ซึ่งทำงานบน Openstack พร้อมแบ็คเอนด์ CEPH
ในระบบเหล่านั้นคุณสามารถใช้-u
ตัวเลือกเพื่อให้บรรลุพฤติกรรมมาตรฐาน:
(gsed -u '/y/ q'; echo aaa; cat) </tmp/test
และสำหรับท่อ:
$ cat test | (gsed -u '/y/ q'; echo aaa; cat)
xxx
yyy
aaa
zzz
ซึ่งนำไปสู่ประสิทธิภาพที่ไม่มีประสิทธิภาพอย่างมากเพราะsed
ต้องอ่านทีละหนึ่งไบต์ เอาท์พุทบางส่วนจากstrace
:
$ strace -fe read sh -c '{ sed -u "/y/q"; echo aaa; cat; } <test'
...
[pid 5248] read(3, "", 4096) = 0
[pid 5248] read(0, "x", 1) = 1
[pid 5248] read(0, "x", 1) = 1
[pid 5248] read(0, "x", 1) = 1
[pid 5248] read(0, "\n", 1) = 1
xxx
[pid 5248] read(0, "y", 1) = 1
[pid 5248] read(0, "y", 1) = 1
[pid 5248] read(0, "y", 1) = 1
[pid 5248] read(0, "\n", 1) = 1
yyy
...
cat
(ในเชลล์ย่อย) สามารถใช้ file descriptor อีกครั้งในกรณีแรกเนื่องจาก stdin ถูกผูกไว้กับไฟล์จริง ในกรณีที่สอง stdin มาจากไพพ์และไม่ใช่ไฟล์จริง ทราบว่ายังไม่ได้พิมพ์(sed '/y/ q'; echo aaa; cat) < <(cat test)
zzz