¿Cómo escribir todo el búfer en la salida estándar desde la línea de comandos?

10

Me gustaría escribir todo el búfer en la salida estándar ( /dev/stdout) en lugar del archivo y el siguiente comando funciona como se esperaba al editar el archivo:

:w >> /dev/stdout

Sugerencia: presione Control+ Lpara actualizar la pantalla.

Pero no funciona como se esperaba cuando intento hacer lo mismo desde la línea de comandos (de forma no interactiva ), por ejemplo:

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

Lo mismo con :w !tee, :x! /dev/stdout, :%printy similar.

Antes de dejar de fumar, es decir: [Device] 1L, 17C appended.

¿Hay alguna forma de forzar a vim a escribir la entrada estándar en la salida estándar en el medio de una tubería? Tal vez es de alguna manera amortiguado?

kenorb
fuente
44
Por curiosidad, ¿qué estás tratando de lograr? Como en, ¿qué hará vim por usted aquí que alguna otra herramienta podría no?
Jay Thompson
1
@ JayThompson Estoy tratando de usar vimpara el análisis de archivos en lugar de sed(por ejemplo, cambios complejos repetidos en masa a múltiples archivos grandes). El ejemplo no hace nada para mantenerlo simple y no hacer un posible duplicado de otra publicación .
kenorb
Usted sabe acerca de vipe, ¿por alguna razón no lo está usando?
muru
@muru Todavía no lo usé, no hay mucha documentación disponible y está fuera de tema aquí.
kenorb
Pueden ser preguntas sobre vipe, pero no hay razón para que no sea la respuesta. Así que me pregunto por qué no debería publicarlo como respuesta.
muru

Respuestas:

9

Para imprimir la salida estándar del búfer a la shell, vimdebe comenzar en modo Ex, de lo contrario, se abrirá de manera "normal" con su propia ventana y borrará cualquier búfer de salida al salir.

Aquí está el ejemplo de trabajo más simple:

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

o incluso más corto:

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

Nota: El comando vim -ees básicamente equivalente al excomando.

Es necesario especificar un descriptor de archivo especial para la entrada estándar ( /dev/stdin) para evitar mensajes molestos adicionales (como se explica a continuación).


Y aquí hay algunos ejemplos con cadenas de análisis:

$ 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.

Nota: El último ejemplo muestra un mensaje molesto adicional que no es posible ocultarlo, es porque es una estrategia estándar de leer todo el archivo en la memoria y decir que se leyó desde la entrada estándar. El primer ejemplo funciona sin el mensaje, porque el archivo produce datos sin fin sin una señal de fin de archivo ( EOF ), por lo que nunca llegará al final de su lectura de entrada.


Relacionado:

kenorb
fuente
1
Puedes hacerlo en +q!lugar de +:q!, ¿verdad?
Andrew
@ AndrewMacFie Es lo mismo, actualizado, gracias.
kenorb
3

vipees una herramienta conveniente para editar tuberías, parte del moreutilspaquete. Es un contenedor para editores (incluido el vique le da su nombre). Se utiliza la EDITORvariable de entorno para configurar el editor, por lo que, al igual que con otras herramientas que hacen uso de EDITOR(tales como crontab, visudo, etc.), puede acciones de script utilizando esa variable. Por ejemplo, puede cambiarlo para hacer:

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

Por supuesto, las acciones complicadas podrían convertirse en citas del infierno, por lo que podría escribir un script:

#! /bin/sh

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

Y uso EDITOR="sh /path/to/script".

muru
fuente