โปรแกรมที่สามารถบัฟเฟอร์ stdin หรือไฟล์


12

นอกเหนือจากการใช้แฟ้มชั่วคราวเพื่อช่วยเหลือมีวิธี / โปรแกรมอาจบัฟเฟอร์ข้อมูลจากแต่ไม่ออกเนื้อหาจนกว่าจะได้รับstdin EOFฉันไม่ต้องการใช้ตัวแปรเชลล์ (เช่นbuffer=$(cat))

โปรแกรมนี้ควรทำงานตามด้านล่าง (สมมติว่าชื่อโปรแกรมคือbuffered-cat)

$ buffered-cat
line 1
line 2
line 3
^D # Ctr-D here(End of Line)

หลังจากที่โปรแกรมได้รับ^Dแล้วbuffered-catส่งออกเนื้อหา

line 1
line 2
line 3

ปกติฉันใช้sortเพื่อจุดประสงค์นี้ เห็นได้ชัดว่ามันมีผลข้างเคียงที่อาจไม่พึงประสงค์
Adrian Pronk

คำตอบ:


20

คนยากจนspongeใช้awk:

awk '{a[NR] = $0} END {for (i = 1; i <= NR; i++) print a[i]}'

หากคุณมีtacคุณสามารถใช้ในทางที่ผิดเช่นกัน:

... | tac | tac

1
tacฉันคิดว่าเรียบง่ายและสง่างาม
Ekeyme Mo

6
@EkeymeMo | tac | tac นั้นง่าย แต่จำไว้ว่ามันไม่มีประสิทธิภาพสูงสำหรับงานและคุณจะได้รับผลกระทบจากการทำงานโดยเฉพาะไฟล์ขนาดใหญ่
บาดเจ็บทางดิจิตอล

@ DigitalTrauma ใช่ฉันรู้ข้อเสียของมัน ฉันทดสอบไฟล์ที่มี 100,000 บรรทัด มันโอเคสำหรับฉัน. ฉันโหวตความคิดเห็นของคุณตามจริง
Ekeyme Mo

29

คุณสามารถทำสิ่งนี้ได้spongeจากมากขึ้นโดยใช้ spongeจะ "ดูดซับอินพุตมาตรฐานและเขียนลงไฟล์" ไม่มีอาร์กิวเมนต์ไฟล์นั้นเป็นเอาต์พุตมาตรฐาน อินพุตที่กำหนดให้กับคำสั่งนี้จะถูกเก็บไว้ในหน่วยความจำจนกระทั่ง EOF แล้วเขียนออกมาทั้งหมดในครั้งเดียว

สำหรับการเขียนไฟล์ปกติคุณสามารถให้ชื่อไฟล์ได้:

cmd | sponge filename

วัตถุประสงค์หลักของspongeการอนุญาตให้อ่านและเขียนจากไฟล์เดียวกันภายในไปป์ไลน์ แต่ก็ทำในสิ่งที่คุณต้องการเช่นกัน


6

ตราบใดที่อินพุตของคุณคือข้อความ ASCII (ไม่มี NUL 0x0 ไบต์จนถึงจุดสิ้นสุด) จากนั้นsed -zทำสิ่งที่คุณต้องการ:

$ sed -z ''
Line 1
Line 2
Line 3
^D
Line 1
Line 2
Line 3
$ 

-zสาเหตุsedการรักษาไบต์ NUL เป็นตัวคั่นบรรทัดแทนการขึ้นบรรทัดใหม่ตามปกติ ดังนั้นตราบใดที่อินพุตของคุณเป็นข้อความปกติที่ไม่มี NUL ไบต์แล้ว sed จะอ่านค่าอินพุตทั้งหมดในบัฟเฟอร์รูปแบบต่อไปจนกว่า EOF จะถึง sedจากนั้นจะไม่ทำการประมวลผลบนบัฟเฟอร์และส่งออก


หาก NUL มีอยู่ในอินพุตของคุณคุณสามารถทำได้แทน:

sed ':l;N;bl'


1

พฤติกรรมที่คุณต้องการไม่ใช่พฤติกรรมปกติของแมวธรรมดาใช่มั้ย

gv@debian:$ cat << EOF #or cat <<EOF >file or cat <<EOF >/dev/stdout
> Line 1
> Line 2
> Line 3
> EOF
Line 1
Line 2
Line 3
gv@debian:$

3
ไม่นั่นเป็นลักษณะการทำงานของเอกสารที่นี่ ลองพิมพ์cat(Enter) Line 1(Enter) แล้วดูว่าเกิดอะไรขึ้น
G-Man กล่าวว่า 'Reinstate Monica'

ใช่นั่นคือโครงสร้าง doc ที่นี่ เรียบง่ายและใกล้เคียงกับสิ่งที่ OP ต้องการ ไม่จำเป็นต้องติดตั้งเช่นกัน
Sergiy Kolodyazhnyy

1

แนวคิดเช่นเดียวกับตัวอย่าง awk ของ muru ยกเว้นใน Python ใช้CtrlDเพื่อหยุดอ่านในบรรทัด

$ python -c 'import sys;print("".join(sys.stdin.readlines()))'                                                           
line1
line2
line3 # press Enter and Ctrl+D at this point
line1
line2
line3

3
หรือperl -e 'print <>'(!)
dave_thompson_085
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.