Apakah mungkin untuk mem-pipe perintah vim ke vim?


18

Saya ingin menjalankan shell berikut.

wea-this is the end of the second word | vim j
exit 0

Yang saya harapkan akan menyalurkan pukulan tombol w(memajukan kata) kemudian e(akhir kata) lalu a(menambahkan) kemudian -this is the end of the second word(teks) ke dokumen Vim bernama jyang sudah memiliki kata-kata di dalamnya.

Kesalahan berikut terjadi ketika saya menjalankan skrip shell.

/root/bin/tt.sh: line 1: wea-this: command not found
Vim: Warning: Input is not from a terminal

Saya menjalankan Ubuntu 14.04. Dua jenis jawaban akan dihargai:

  1. Cara menggunakan perpipaan untuk mencapai hasil yang diinginkan ini.
  2. Metode lain yang saya gunakan "perintah Vim" (bukan perintah ed atau sed) untuk mengedit dokumen teks dari skrip shell.

1
The |pipa karakter output dari satu perintah yang lain. wea-thisbukan perintah. Perpipaan tidak dapat digunakan untuk mencapai apa yang Anda inginkan; itu akan menyebabkan stdin Vim menjadi aplikasi sebelah kiri, bukan keyboard. Jika Anda ingin mendapatkan stdin ke dalam buffer di vim, mulai dengan minus untuk nama file: echo Hello, world! | vim -.
dash-tom-bang

Jawaban:


15

Untuk memasukkan string "hello"pada baris pertama file j, Anda bisa mengetikkan shell Anda perintah berikut:

vim +"1 | put! ='hello'" j

  • :1 memindahkan kursor ke baris pertama buffer
  • :put! ='hello' menempelkan string "halo" di atas garis saat ini

Untuk memasukkan string "hello"dan kemudian menyimpan dan keluar dari file:

vim +"1 | put! ='hello' | x" j

Sama seperti sebelumnya, kami baru saja menambahkan perintah Ex :xyang menyimpan dan keluar.

Secara umum, Anda dapat menjalankan urutan perintah Ex pada file, dari shell interaktif atau dari skrip bash, seperti ini:

vim +'Ex command1 | Ex command2 | ...' file

Jika Anda memiliki banyak perintah Ex, Anda dapat menuliskan semuanya di dalam file khusus (disebut misalnya myExCommands.vim), satu perintah per baris, dan kemudian dari shell atau skrip yang Anda dapat sumbernya (dengan perintah Ex :sourceatau versi singkatnya) :so) seperti ini:

vim +'so myExCommands.vim' file

Edit

Saya melihat Anda telah mengedit pertanyaan Anda.
Saya pikir jawaban sebelumnya masih berlaku, karena Anda dapat menjalankan perintah normal dari mode Ex dengan perintah Ex :normaldan :execute.

Misalnya, katakanlah Anda ingin:

  • pindahkan kursor Anda pada baris pertama buffer ( 1G)
  • pindahkan kursor Anda ke karakter bukan spasi pertama di baris ( _)
  • gerakkan kursor Anda satu kata ke depan ( w)
  • pindahkan kursor Anda ke akhir kata baru ( e)
  • masuk ke mode insert setelah karakter di bawah kursor ( a)
  • masukkan string hello
  • simpan dan keluar ( :x)

Untuk melakukan ini pada file j, ketik dari shell:

vim +"execute 'normal! 1G_weahello' | x" j

Untuk informasi lebih lanjut, lihat:

:help +cmd
:help :normal
:help :execute

Saya gagal mengklarifikasi tujuan saya sepenuhnya. Saya ingin dapat menggunakan perintah vims, seperti w untuk memajukan suatu kata dan semacamnya. Saya akan mengedit pertanyaan saya untuk memperbaiki.
Jason Basanese

@JasonBasanese Saya sudah mengedit jawaban saya, melakukan perintah Ex :normaldan :executemelakukan apa yang Anda inginkan?
Saginaw

9

Berikut adalah cara Anda dapat menggunakan perintah mode normal, bukan hanya perintah ex, untuk mengedit aliran yang disajikan ke Vim dari stdin. Ini bukan contoh yang sangat berguna, tetapi menggambarkan teknik yang terlibat. Diasumsikan bahwa shell Anda bash.

echo "The brown fox jumped." | vim -s <(printf 'wcwred\e:wq! foo\n') -

The -pada akhirnya memberitahu Vim untuk membaca teks (bukan perintah) dari stdin. The -smemberitahu Vim untuk mengeksekusi penekanan tombol dari file yang ditentukan. Dalam hal ini, file tersebut adalah output dari substitusi proses bash. The <(...)diganti dengan nama pipa bernama. Output dari pipa adalah output dari perintah di dalam tanda kurung. The wcwred\ebergerak kursor dengan satu kata dan perubahan kata sebelah red. The :wq! foo\nmenyimpan hasil ke file foobahkan jika file yang sudah ada. Hasil akhirnya adalah file bernama foomengandung teksThe red fox jumped.

Untuk lebih lanjut tentang beberapa topik tersebut, lihat

:help -file
:help -s

Lihat juga Process Substitutionbagian bash(1)halaman manual.


Ditambahkan ke saya ~ / Zshrc: vimx () { vi -s <(echo "$1"':wq') "$2" &> /dev/null; }. Sekarang saya bisa vimx 'iThe brow fox jumped.\e' foo; vimx 'wcwred\efjdwiclimbed\e' foo; cat foo. Rapi!
Leonard Pauli

4

Saya telah menemukan metode untuk mengambil output dari sebuah program yang dialihkan dari sub-shell menjadi sangat mudah:

vim <( program )

Contoh:

 vim <( grep -nH  hello  myFile.cpp )
 vim <( find . -name '*.cpp' -exec grep -nH code_expr {} \+ )

4

Saya memiliki keinginan yang sama persis seperti Anda: Saya ingin menulis perintah vim normal dan meminta mereka mengedit aliran pipa. Saya kecewa dengan kesulitan menggunakan vim normal dengan cara ini (begitu banyak flag!), Seperti yang disediakan oleh opsi vim default.

Oleh karena itu, saya menulis pembungkus kecil di vim untuk melakukannya: https://github.com/MilesCranmer/vim-stream/ . Itu disebut vims.

Inti bungkusnya adalah perintah berikut:

vim - -nes "${vim_cmds[@]}" -c ':q!' | tail -n +2

Dengan menggunakan ini, dengan generasi perintah yang saya lakukan, hasilnya cukup ringkas, dan karena vim adalah editor modal, saya membuat vimseditor aliran modal. Ada tiga mode utama yang berguna untuk mentalitas penyuntingan pipa:

[-t|--turn-off-mode] - (Default mode)
                       Every string is a vim command line, e.g., '%g/foo/d' deletes
                       all lines with foo.
[-e|--exe-mode] -      Translated to '%g/$1/exe "norm $2"', see examples below
[-s|--simple-mode] -   Like exe-mode, but runs on 1st line only

Menonton ini:

$ echo "Hello World" | vims -s "ea Beautiful"
Hello Beautiful World

Jadi, elanjutkan ke akhir Hello, lalu amulai menambahkan.

Sesuatu yang lebih menarik, dalam mode exe, untuk mengomentari baris yang berisi my_bad_var, dan menghapus baris sebelumnya.

cat my_script.cpp | vims -e 'my_bad_var' 'I//\<esc>kdd'

Yang diterjemahkan menjadi vims '%g/my_bad_var/exe "norm I//\<esc>kdd"'- Iperintah untuk mulai memasukkan di awal baris, dan //menjadi urutan komentar. \<esc>kddmenekan tombol escape, bergerak ke atas garis, lalu menghapus garis.

Saya punya 11 contoh total pada repo itu, saya mendorong Anda untuk memeriksanya. Sekali lagi, ini berjalan di atas vim, itu hanya cara untuk membuat vim lebih seperti sed untuk input stream (tetapi menjaga semua makro vim kesayangan Anda!)


3

Ini adalah pertanyaan yang cukup lama, tetapi saya merasa layak untuk berkontribusi bahwa jika distro / OS Anda memiliki akses moreutils, maka Anda dapat menginstalnya dan hanya menggunakan vipesebagai tambahan standar untuk vim:

echo foo | vipe # Now you can edit "foo" to be "bar"!

moreutilssangat berguna untuk alat-alat lainnya, dan saya akan sangat merekomendasikan mereka jika Anda adalah pengguna baris perintah yang serius! :) Lihatlah pengantar penulis (tautan sebelumnya) untuk lebih jelasnya.

moreutilsseharusnya tersedia secara umum untuk kebanyakan distro * nix-like melalui manajer paket dan melalui Homebrew pada Mac . Sebagai contoh...

# Arch Linux and MSYS2 (more below) as part of the `community` repo
pacman -Sy moreutils


# Mac OS and Homebrew
brew install moreutils

moreutilsjuga merupakan bagian dari repositori paket MSYS2 , sehingga Anda secara teknis dapat menggunakannya pada Windows juga. :)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.