Comment écrire tout le tampon sur la sortie standard à partir de la ligne de commande?

10

Je voudrais écrire tout le tampon dans la sortie standard ( /dev/stdout) au lieu du fichier et la commande suivante fonctionne comme prévu lors de l'édition du fichier:

:w >> /dev/stdout

Astuce: Appuyez sur Control+ Lpour rafraîchir l'écran.

Mais cela ne fonctionne pas comme prévu lorsque j'essaie de faire la même chose à partir de la ligne de commande (de manière non interactive ), par exemple:

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

La même chose avec :w !tee, :x! /dev/stdout, :%printet similaire.

Avant de quitter, il est dit: [Device] 1L, 17C appended.

Existe-t-il un moyen de forcer vim à écrire l'entrée standard dans la sortie standard au milieu d'un tuyau? Peut-être que c'est en quelque sorte tamponné?

Kenorb
la source
4
Juste curieux, qu'essayez-vous d'accomplir? Comme dans, qu'est-ce que vim fera pour vous ici qu'un autre outil pourrait ne pas faire?
Jay Thompson
1
@JayThompson J'essaie d'utiliser vimpour l'analyse de fichiers au lieu de sed(par exemple, des modifications complexes répétées en masse de plusieurs gros fichiers). L'exemple ne fait rien pour rester simple et ne pas faire de doublon potentiel d'un autre article .
kenorb
Vous connaissez vipe, alors pourquoi ne l'utilisez-vous pas?
muru
@muru Je ne l'ai pas encore utilisé, pas beaucoup de documentation disponible et c'est hors sujet ici.
kenorb
Des questions sur vipe peuvent être, mais il n'y a aucune raison que ce ne soit pas la réponse. Je me demande donc pourquoi je ne devrais pas l'afficher comme réponse.
muru

Réponses:

9

Pour imprimer le tampon sur la sortie standard du shell, vimdoit démarrer en mode Ex, sinon il s'ouvrira de manière "normale" avec sa propre fenêtre et effacera tous les tampons de sortie à la fermeture.

Voici l'exemple de travail le plus simple:

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

ou encore plus court:

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

Remarque: La commande vim -eest fondamentalement équivalente à la excommande.

Un descripteur de fichier spécial pour l'entrée standard doit être spécifié ( /dev/stdin) afin d'éviter des messages supplémentaires gênants (comme expliqué ci-dessous).


Et voici quelques exemples d'analyse de chaînes:

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

Remarque: Le dernier exemple montre un message ennuyeux supplémentaire qui n'est pas possible de le cacher, c'est parce qu'une stratégie standard de lire le fichier entier en mémoire et de dire qu'il a été lu à partir de l'entrée standard. Le premier exemple fonctionne sans le message, car le fichier produit des données sans fin sans signal de fin de fichier ( EOF ), il n'atteindra donc jamais la fin de sa lecture d'entrée.


En relation:

Kenorb
la source
1
Vous pouvez simplement faire +q!plutôt que +:q!, non?
Andrew
@AndrewMacFie C'est la même chose, mis à jour, merci.
kenorb
3

vipeest un outil pratique pour éditer des pipelines, qui fait partie du moreutilspackage. Il s'agit d'un wrapper pour les éditeurs (y compris levi qui lui donne son nom). Il utilise la EDITORvariable d'environnement pour définir l'éditeur, donc, comme avec d' autres outils qui utilisent EDITOR( par exemple crontab, visudoetc.), vous pouvez les actions de script en utilisant cette variable. Par exemple, vous pouvez le modifier pour faire:

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

Bien sûr, des actions compliquées peuvent aller jusqu'à citer l'enfer, vous pouvez donc écrire un script:

#! /bin/sh

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

Et utilisez EDITOR="sh /path/to/script".

muru
la source