cat <<EOS | sed -ne '1{h;d;}' -e 'H;${G;p;}'
line 1
line 2
line 3
EOS
ปัญหาเกี่ยวกับการแปลสิ่งนี้เป็นสิ่งที่ใช้tailคือtailต้องอ่านไฟล์ทั้งหมดเพื่อค้นหาจุดสิ้นสุด หากต้องการใช้สิ่งนั้นในไปป์ไลน์ของคุณคุณต้อง
- ให้เนื้อหาเต็มของเอกสารถึง
tailให้เนื้อหาทั้งหมดของเอกสารที่จะ
- ให้มันอีกครั้งเพื่อ
catเพื่อ
- เพื่อให้.
บิตที่ยุ่งยากนั้นไม่ได้เป็นการทำซ้ำเนื้อหาของเอกสาร ( teeทำเช่นนั้น) แต่เพื่อให้ได้ผลลัพธ์ที่tailจะเกิดขึ้นก่อนที่จะเอาท์พุทที่เหลือของเอกสารโดยไม่ต้องใช้ไฟล์ชั่วคราวระดับกลาง
ใช้sed(หรือawkเป็น John1024 ทำ ) กำจัดการแยกวิเคราะห์ข้อมูลและปัญหาการสั่งซื้อโดยการเก็บข้อมูลไว้ในหน่วยความจำ
sedแก้ปัญหาที่ผมเสนอคือการ
1{h;d;}จัดเก็บบรรทัดแรกในพื้นที่พักตามที่เป็นอยู่และข้ามไปที่บรรทัดถัดไป
Hต่อท้ายแต่ละบรรทัดไปที่พื้นที่พักด้วยการขึ้นบรรทัดใหม่
${G;p;}ต่อท้ายพื้นที่พักไว้ที่บรรทัดสุดท้ายด้วยการขึ้นบรรทัดใหม่และพิมพ์ข้อมูลผลลัพธ์
นี่เป็นการแปลตามตัวอักษรอย่างแท้จริงของวิธีแก้ปัญหาของ John1024 sedโดยข้อแม้ที่ว่ามาตรฐาน POSIX รับประกันได้ว่าพื้นที่พักค้างนั้นจะไม่เกิน 8192 ไบต์ (8 KiB แต่แนะนำว่าบัฟเฟอร์นี้จะถูกจัดสรรแบบไดนามิกและขยายตามความจำเป็นซึ่ง GNU ทั้งสองsedและ BSD sedกำลังทำอยู่)
หากคุณอนุญาตให้คุณใช้ไพพ์ที่มีชื่อ:
mkfifo mypipe
cat <<EOS | tee mypipe | cat <( tail -n 1 mypipe ) -
line 1
line 2
line 3
EOS
rm -f mypipe
ใช้สิ่งนี้teeในการส่งข้อมูลลงและในเวลาเดียวกันmypipe ยูทิลิตี้ครั้งแรกที่จะอ่านเอาท์พุทจาก(ซึ่งอ่านจากที่มีการเขียนถึง) แล้วผนวกสำเนาของเอกสารมาโดยตรงจากcatcattailmypipeteetee
มีข้อบกพร่องร้ายแรงในเรื่องนี้แม้ว่าในกรณีที่เอกสารมีขนาดใหญ่เกินไป (ใหญ่กว่าขนาดบัฟเฟอร์ของไปป์) teeการเขียนmypipeและcatจะบล็อกในขณะที่รอให้ท่อ (ไม่มีชื่อ) ว่างเปล่า มันจะไม่ถูกทำให้ว่างจนกว่าจะcatอ่านจากมัน catจะไม่อ่านจนกว่าtailจะเสร็จ และtailจะไม่เสร็จจนกว่าteeจะเสร็จสิ้น นี่คือสถานการณ์การหยุดชะงักแบบคลาสสิก
ความแปรปรวน
tee >( tail -n 1 >mypipe ) | cat mypipe -
มีปัญหาเดียวกัน