Bagaimana cara menulis buffer keseluruhan ke output standar dari baris perintah?

10

Saya ingin menulis seluruh buffer ke dalam output standar ( /dev/stdout) alih-alih file dan perintah berikut berfungsi seperti yang diharapkan saat mengedit file:

:w >> /dev/stdout

Petunjuk: Tekan Control+ Luntuk menyegarkan layar.

Tapi itu tidak berfungsi seperti yang diharapkan ketika saya mencoba melakukan hal yang sama dari baris perintah ( non-interaktif ), misalnya:

$ echo This is example. | vim - '+:w >> /dev/stdout' '+:q!'
Vim: Reading from stdin...

Sama dengan :w !tee, :x! /dev/stdout, :%printdan yang sejenis.

Sebelum berhenti, itu mengatakan: [Device] 1L, 17C appended.

Apakah ada cara memaksa vim untuk menulis input standar ke output standar di tengah pipa? Mungkin itu entah bagaimana buffered?

kenorb
sumber
4
Hanya ingin tahu, apa yang ingin Anda capai? Seperti pada, apa yang akan dilakukan vim untuk Anda di sini yang mungkin tidak dilakukan oleh alat lain?
Jay Thompson
1
@JayThompson Saya mencoba menggunakan vimuntuk parsing file alih-alih sed(mis., Perubahan kompleks berulang untuk beberapa file besar). Contohnya tidak melakukan apa pun untuk membuatnya tetap sederhana dan tidak membuat duplikat potensial dari posting lain .
kenorb
Anda tahu tentang vipe, jadi ada alasan Anda tidak menggunakannya?
muru
@muru Saya belum menggunakannya, tidak banyak dokumentasi tersedia dan di luar topik di sini.
kenorb
Pertanyaan tentang vipe mungkin, tetapi tidak ada alasan itu tidak bisa menjadi jawabannya. Jadi saya bertanya-tanya mengapa saya tidak mempostingnya sebagai jawaban.
muru

Jawaban:

9

Untuk mencetak buffer ke shell keluaran standar, vimperlu mulai dalam mode Ex, jika tidak, ia akan membuka cara "normal" dengan jendela sendiri dan menghapus semua buffer output saat berhenti.

Berikut ini contoh kerja paling sederhana:

$ echo foo | vim -e '+%print' '+q!' /dev/stdin
foo

atau bahkan lebih pendek:

$ echo foo | ex +%p -cq! /dev/stdin
$ echo foo | ex +"%p|q!" /dev/stdin

Catatan: Perintah vim -eini pada dasarnya setara dengan experintah.

Deskriptor file khusus untuk input standar perlu ditentukan ( /dev/stdin) untuk mencegah pesan tambahan yang mengganggu (seperti yang dijelaskan di bawah).


Dan berikut adalah beberapa contoh dengan string parsing:

$ echo This is example. | vim -e '+s/example/test/g' '+%print' '+q!' /dev/stdin
This is test.
$ echo This is example. | vim - -es '+s/example/test/g' '+%print' '+q!'
Vim: Reading from stdin...
This is test.

Catatan: Contoh terakhir menunjukkan pesan tambahan yang menjengkelkan yang tidak mungkin disembunyikan, itu karena strategi standar membaca seluruh file ke dalam memori dan mengatakan itu dibaca dari input standar. Contoh pertama berfungsi tanpa pesan, karena file menghasilkan data tanpa akhir tanpa sinyal end-of-file ( EOF ), sehingga tidak akan pernah mencapai akhir pembacaan inputnya.


Terkait:

kenorb
sumber
1
Anda hanya dapat melakukan +q!bukan +:q!, kan?
Andrew
@AndrewMacFie Itu hal yang sama, diperbarui, terima kasih.
kenorb
3

vipeadalah alat yang mudah untuk mengedit saluran pipa, bagian dari moreutilspaket. Ini adalah pembungkus untuk editor (termasuk viyang memberikan namanya). Ia menggunakan EDITORvariabel lingkungan untuk mengatur editor, jadi, seperti dengan alat-alat lain yang menggunakan EDITOR(seperti crontab, visudo, dll), Anda bisa tindakan script menggunakan variabel tersebut. Misalnya, Anda dapat mengubahnya untuk melakukan:

$ echo foo | EDITOR='vim +:s/foo/bar/ +wq' vipe | tail
bar

Tentu saja, tindakan rumit mungkin beralih ke mengutip neraka, sehingga Anda dapat menulis skrip:

#! /bin/sh

vim "+:s/foo/bar" '+wq' "$@"

Dan gunakan EDITOR="sh /path/to/script".

muru
sumber