Como gravar um buffer inteiro na saída padrão da linha de comando?

10

Gostaria de gravar o buffer inteiro na saída padrão ( /dev/stdout) em vez do arquivo e o seguinte comando funciona conforme o esperado durante a edição do arquivo:

:w >> /dev/stdout

Dica: pressione Control+ Lpara atualizar a tela.

Mas não funciona como esperado quando estou tentando fazer o mesmo na linha de comando ( não interativamente ), por exemplo:

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

O mesmo acontece com :w !tee, :x! /dev/stdout, :%printe semelhantes.

Antes de sair, ele está dizendo: [Device] 1L, 17C appended.

Existe alguma maneira de forçar o vim a gravar a entrada padrão na saída padrão no meio de um tubo? Talvez seja de alguma forma armazenado em buffer?

kenorb
fonte
4
Apenas curioso, o que você está tentando realizar? Como, o que o vim fará por você aqui que outra ferramenta talvez não faça?
Jay Thompson
11
@ JayThompson Estou tentando usar vima análise de arquivos em vez de sed(por exemplo, alterações complexas repetidas em massa em vários arquivos grandes). O exemplo não faz nada para mantê-lo simples e não tornar possível a duplicação de outra postagem .
Kenorb
Você conhece o vipe, então qualquer motivo para não usá-lo?
Muni
@ muru Ainda não o usei, não há muita documentação disponível e está fora de tópico aqui.
Kenorb
As perguntas sobre o vipe podem ser, mas não há motivo para não ser a resposta. Então, eu estou me perguntando por que não devo publicá-lo como resposta.
muru

Respostas:

9

Para imprimir buffer para shell de saída padrão, é vimnecessário iniciar no modo Ex, caso contrário, ele abrirá o modo "normal" com sua própria janela e limpará os buffers de saída ao sair.

Aqui está o exemplo de trabalho mais simples:

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

ou ainda mais curto:

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

Nota: O comando vim -eé basicamente equivalente ao excomando.

É necessário especificar um descritor de arquivo especial para a entrada padrão ( /dev/stdin) para evitar mensagens irritantes extras (como explicado abaixo).


E aqui estão alguns exemplos com análise de strings:

$ 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: O último exemplo mostra uma mensagem irritante extra que não é possível ocultá-la, é porque uma estratégia padrão de ler todo o arquivo na memória e dizer que foi lido a partir da entrada padrão. O primeiro exemplo funciona sem a mensagem, porque o arquivo produz dados infinitos sem um sinal de fim de arquivo ( EOF ), portanto nunca chegará ao final da leitura de entrada.


Relacionado:

kenorb
fonte
11
Você pode simplesmente fazer, +q!e não +:q!, certo?
28417 Andrew
@AndrewMacFie É a mesma coisa, atualizada, obrigado.
22417 kenorb
3

vipeé uma ferramenta conveniente para editar pipelines, parte do moreutilspacote. É um invólucro para editores (incluindo o vique lhe dá nome). Ele usa a EDITORvariável de ambiente para definir o editor, por isso, como com outras ferramentas que fazem uso de EDITOR(tais como crontab, visudo, etc.), você pode ações de script usando essa variável. Por exemplo, você pode alterá-lo para:

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

Obviamente, ações complicadas podem passar a citar o inferno, para que você possa escrever um script:

#! /bin/sh

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

E use EDITOR="sh /path/to/script".

muru
fonte