Sebuah program yang dapat me-buffer stdin atau file

12

Selain menggunakan file sementara untuk membantu, apakah ada cara / program dapat buffer input dari stdintetapi tidak menampilkan konten sampai mendapatkan EOF. Saya juga tidak ingin menggunakan variabel shell (misalnya buffer=$(cat)).

Program ini harus berperilaku seperti di bawah ini (anggap nama programnya buffered-cat):

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

Sekarang setelah program diterima ^D, buffered-catoutput isinya

line 1
line 2
line 3
Ekeyme Mo
sumber
Saya biasanya menggunakan sortuntuk tujuan ini. Jelas itu memiliki efek samping yang mungkin tidak diinginkan.
Adrian Pronk

Jawaban:

20

Seorang pria miskin spongemenggunakan awk:

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

Jika sudah tac, Anda dapat menyalahgunakannya juga:

... | tac | tac
muru
sumber
1
tacsederhana dan elegan, saya pikir.
Ekeyme Mo
6
@EkeymeMo | tac | tac adalah sederhana, tapi ingat bahwa itu adalah sangat tidak efisien untuk tugas dan Anda akan menderita hit kinerja, terutama untuk file yang lebih besar.
Digital Trauma
@DigitalTrauma ya, saya tahu kekurangannya. Saya menguji file dengan 100 ribu baris. Tidak masalah bagi saya. Saya memilih komentar Anda karena itu benar.
Ekeyme Mo
29

Anda dapat melakukannya dengan menggunakan spongemoreutils . spongeakan "menyerap input standar dan menulis ke file". Tanpa argumen, file itu adalah output standar. Input yang diberikan untuk perintah ini disimpan dalam memori hingga EOF, dan kemudian dituliskan sekaligus.

Untuk menulis ke file normal, Anda bisa memberikan nama file:

cmd | sponge filename

Tujuan utamanya spongeadalah untuk memungkinkan membaca dan menulis dari file yang sama dalam suatu pipa, tetapi ia melakukan apa yang Anda inginkan juga.

Michael Homer
sumber
6

Selama input Anda adalah teks ASCII (tidak mengandung NUL 0x0 byte hingga akhir), maka sed -zlakukan apa yang Anda inginkan:

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

The -zpenyebab seduntuk mengobati byte NUL sebagai pembatas jalur bukan baris biasa. Jadi selama input Anda adalah teks biasa tanpa byte NUL, maka sed akan terus membaca seluruh input ke buffer pola sampai EOF tercapai. sedkemudian tidak memproses buffer dan mengeluarkannya.


Jika NUL byte hadir di input Anda, maka Anda bisa melakukan ini sebagai gantinya:

sed ':l;N;bl'
Trauma Digital
sumber
4

Ini sedsolusi sedikit lebih lama dari DigitalTrauma, tetapi juga bekerja dengan NUL byte.

sed -n 'H;${x;s/^\n//;p}'
JoL
sumber
2
sed ':l;N;bl'harus bekerja juga.
Trauma Digital
1

Perilaku yang Anda minta, bukankah itu perilaku standar kucing sederhana?

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:$
George Vasiliou
sumber
3
Tidak, itulah perilaku dokumen di sini. Coba ketikkan cat(Enter) Line 1(Enter) dan lihat apa yang terjadi.
G-Man Mengatakan 'Reinstate Monica'
Yap, itu struktur di sini-doc. Sederhana dan cukup dekat dengan apa yang diinginkan OP. Tidak memerlukan instalasi juga
Sergiy Kolodyazhnyy
1

Gagasan yang sama dengan contoh awak muru, kecuali dengan Python. Gunakan CtrlDuntuk berhenti membaca dalam barisan

$ python -c 'import sys;print("".join(sys.stdin.readlines()))'                                                           
line1
line2
line3 # press Enter and Ctrl+D at this point
line1
line2
line3
Sergiy Kolodyazhnyy
sumber
3
Atau perl -e 'print <>'(!)
dave_thompson_085