Bagaimana cara mengedit file secara non-interaktif (mis. Dalam pipeline)?

24

Saya ingin mengedit file yang diteruskan dalam input pipa menggunakan vim secara non-interaktif atau mengedit file di tempat (mirip dengan sed).

Beberapa contoh menggunakan sed:

$ sed -i'.bak' s/foo/test/g file   # Edit file in-place.
$ cat file | sed s/foo/test/g      # Parse file in pipeline.

Namun saya dapat membaca di sini , bahwa:

sedadalah S tream ED itor, bukan file editor. Namun demikian, orang di mana-mana cenderung menyalahgunakannya karena mencoba mengedit file. Itu tidak mengedit file.

Kedua beberapa opsi seperti in-place editing ( -i) bersifat portable.

Bagaimana fungsi yang sama dapat dicapai di vim?

kenorb
sumber
Saya pikir Anda bisa membuang yang kedua filedari commandline kedua Anda.
joeytwiddle
@joeytwiddle Selesai.
kenorb

Jawaban:

33

Untuk mengedit file yang tidak menggunakan interaksi ex( viadalah mode visual untuk ex), Anda dapat menggunakan +{command}atau -c {command}parameter yang memungkinkan Anda untuk menjalankan perintah vi setelah file pertama dibaca.

Ini exadalah editor baris perintah standar (mirip dengan ed).

Ada juga vipe(editor pipa perintah Vim) harus digunakan yang merupakan bagian dari moreutilspaket dan itu akan memungkinkan Anda untuk menjalankan editor Anda di tengah-tengah pipa unix dan mengedit data yang sedang disalurkan antara program.

Contohnya

Input dan output standar sederhana menggunakan pipa dapat dicapai dengan sintaksis shell ini:

$ ex -sc'%p|q!' <(echo Example)
$ echo Example | ex -sc'%p|q!' /dev/stdin

Berikut ini adalah contoh sederhana cara mencetak file setelah substitusi:

$ ex /etc/hosts +%s/127/128/ge -sc'%p|q!'

Lebih banyak contoh untuk mengedit file di tempat:

$ ex +'%s/127/128/g' -cswq file
$ ex -sc '%s/olddomain\.com/newdomain.com/g|x' file
$ printf '%s\n' 'g/olddomain\.com/s//newdomain.com/g' w q | ex -s file
$ ex -s "$file" <<< $'g/old/s//new/g\nw\nq'
$ ex -sc 'argdo %s/old/new/ge|x' ./**
$ find . -type f -exec ex -sc '%s/old/new/g|x' {} \;

Anda juga dapat menggunakan -s {scriptin}sehingga perintah diambil dari file, misalnya:

$ printf "%s\n" '%s/foo/test/ge' 'wq' > cmds.vim
$ vim -s cmds.vim -es file

atau menggunakan pengalihan I / O:

$ vim file < cmds.vim

Untuk mengedit satu file dan menyimpan perubahan ke yang lain, periksa contoh berikut:

$ ex +%s/127/128/g -sc'wq! new_file' /etc/hosts
$ cat /etc/hosts /etc/fstab | vim - -es '+:%s/foo/test/g' '+:wq! file3'

Contoh yang lebih praktis.

Contoh nyata dari spesifikasi RPM :

vim -E -s Makefile <<-EOF
   :%substitute/CFLAGS = -g$/CFLAGS =-fPIC -DPIC -g/
   :%substitute/CFLAGS =$/CFLAGS =-fPIC -DPIC/
   :%substitute/ADAFLAGS =$/ADAFLAGS =-fPIC -DPIC/
   :update
   :quit
EOF

Mengekstrak tag html :

ex -s +'bufdo!/<div.*id=.the_div_id/norm nvatdggdG"2p' +'bufdo!%p' -cqa! *.html

Menghapus tag XML :

ex -s +'%s/<[^>].\{-}>//ge' +%p +q! file.txt

Menghapus tag gaya dari header dan mencetak output yang diuraikan:

curl -s http://example.com/ | ex -s +'/<style.*/norm nvatd' +%p -cq! /dev/stdin

Parsing html dengan beberapa aturan kompleks:

ex -V1 $PAGE <<-EOF
  " Correcting missing protocol, see: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2359 "
  %s,'//,'http://,ge
  %s,"//,"http://,ge
  " Correcting relative paths, see: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2359 "
  %s,[^,]\zs'/\ze[^>],'http://www.example.com/,ge
  %s,[^,]\zs"/\ze[^>],"http://www.example.com/,ge
  " Remove the margin on the left of the main block. "
  %s/id="doc_container"/id="doc_container" style="min-width:0px;margin-left : 0px;"/g
  %s/<div class="outer_page/<div style="margin: 0px;" class="outer_page/g
  " Remove useless html elements. "
  /<div.*id="global_header"/norm nvatd
  wq " Update changes and quit.
EOF

Bahkan lebih banyak contoh:


Lihat juga:


kenorb
sumber
5
Ini adalah UUOC ; cukup gunakan vim '+:0,$s/foo/test/g' '+:wq! file2' file1saja.
Gagang pintu
2
Perhatikan bahwa setidaknya beberapa contoh ini tidak sesuai dengan POSIX, misalnya bufdo,. Meskipun Vim adalah apa yang diinstal secara virtual di mana-mana, perlu diketahui bahwa Anda dapat mengedit file script hanya menggunakan fitur-fitur yang sesuai dengan POSIXex .
Wildcard
Pertanyaan & jawaban ini adalah yang pertama mengilhami saya untuk melihat exdan benar-benar mempelajarinya. Terima kasih. Beberapa bacaan lebih lanjut tentang subjek ini (pengungkapan penuh: Saya menulis ini;) adalah: membalikkan setiap empat baris denganex , dan menggunakan -copsi . Anda dapat menambahkannya ke daftar tautan di bagian bawah, jika diinginkan. :)
Wildcard