¿Cómo editar archivos de forma no interactiva (p. Ej. En canalización)?

24

Me gustaría editar archivos pasados ​​en entrada de canalización usando vim de manera no interactiva o editar archivos en el lugar (similar a sed).

Pocos ejemplos usando sed:

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

Sin embargo, podría leer aquí que:

sedes un S TREAM ED itor, no un editor de archivos. Sin embargo, las personas en todas partes tienden a abusar de él por tratar de editar archivos. No edita archivos.

En segundo lugar, algunas opciones, como la edición in situ ( -i), son portables.

¿Cómo se puede lograr la misma funcionalidad en vim?

kenorb
fuente
Creo que puedes soltar el segundo filede tu segunda línea de comando.
joeytwiddle
@joeytwiddle Hecho.
kenorb

Respuestas:

33

Para editar archivos de manera no interactiva ex( vies el modo visual para ex), puede usar +{command}o -c {command}parámetros que le permitan ejecutar los comandos vi después de que se haya leído el primer archivo.

El exes un editor de línea de comandos estándar (similar a ed).

También se vipedebe usar un (editor de canalización de comandos Vim) que es parte del moreutilspaquete y le permitirá ejecutar su editor en medio de una canalización de Unix y editar los datos que se canalizan entre los programas.

Ejemplos

La entrada y salida estándar simple mediante tuberías se puede lograr mediante esta sintaxis de shell:

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

Aquí hay un ejemplo simple de cómo imprimir el archivo después de la sustitución:

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

Más ejemplos para editar archivos en el lugar:

$ 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' {} \;

También puede usarlo -s {scriptin}para que los comandos se carguen desde el archivo, por ejemplo:

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

o usando la redirección de E / S:

$ vim file < cmds.vim

Para editar un archivo y guardar los cambios en otro, consulte los siguientes ejemplos:

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

Más ejemplos prácticos.

Ejemplo real en vivo de la especificación 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

Extrayendo etiquetas html :

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

Eliminar etiquetas XML :

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

Eliminar la etiqueta de estilo del encabezado e imprimir la salida analizada:

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

Analiza html con múltiples reglas complejas:

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

Aún más ejemplos:


Ver también:


kenorb
fuente
55
Este es un UUOC ; simplemente use vim '+:0,$s/foo/test/g' '+:wq! file2' file1en su lugar.
Pomo de la puerta
2
Tenga en cuenta que al menos algunos de estos ejemplos no son compatibles con POSIX, por ejemplo bufdo. A pesar de que Vim es lo que está instalado prácticamente en todas partes, vale la pena saber que puede editar archivos de script utilizando solo las funciones compatibles con POSIXex .
Comodín el
Esta pregunta y respuesta es lo que primero me inspiró a investigar exy realmente aprenderlo. Gracias. Algunas lecturas adicionales sobre este tema (divulgación completa: escribí esto;) es: invertir cada cuatro líneas conex y usar la -copción . Puede agregarlos a su lista de enlaces en la parte inferior, si lo desea. :)
Comodín