Come modificare il contenuto dall'input standard?


15

Vorrei modificare il contenuto in VIM che è stato generato dinamicamente dalla riga di comando senza avere ancora il file.

Per esempio:

$ echo This is example. | vim /dev/stdin
$ cat /etc/hosts | vim /dev/stdin

ma non riesce con gli errori:

Vim: Avviso: l'ingresso non proviene da un terminale

Vim: errore durante la lettura dell'input, in uscita ...

È possibile raggiungerlo?


:help stdin... È incredibile quanto velocemente si possano trovare le risposte ponendo la loro domanda sulla documentazione integrata.
dash-tom-bang

Risposte:


23

Devi usare -al posto del nome del file sulla riga di comando:

echo This is example. | vim -

Il comando sopra aprirà un buffer senza nome riempito con il testo letto dallo standard input.


7
L'uso di un -for stdin è praticamente standard per gli strumenti a riga di comando;
Martin Tournoij,

6

Questa è principalmente una nota divertente su bashe readline, ma se imposti la EDITORvariabile di ambiente su vim, premendo Ctrl+ x+ esi aprirà la riga corrente in vim. Inoltre, se si digita Meta(Alt/Opt/Esc)+ Ctrl+ e, bash eseguirà un'espansione sul posto sulla riga di comando corrente, ovvero:

$ echo $EDITOR # Assuming EDITOR was set

con Meta(Alt/Opt/Esc)+ Ctrl+ ediventerebbe

$ echo vim # Assuming EDITOR was set

con Ctrl+ x+ ediventerebbe

1 echo vim # Assuming EDITOR was set
~
~
/tmp/sometmpbufferfile

Si noti che dopo aver chiuso vim, i contenuti del buffer vim vengono eseguiti sulla riga di comando.

Queste funzioni diventano molto utili per me quando voglio fare comandi multilinea in bash come loop o programmi che richiedono istruzioni qui, e fornisce un modo interessante per salvare un po 'di cronologia della riga di comando su file per un uso successivo.

Quindi, per rispondere alla domanda originale, puoi anche scrivere,

$ This is an example

e quindi premi Ctrl+ x+ eper caricarlo vim. Inoltre potresti avere,

 $ $(cat /etc/hosts)

e fai Meta(Alt/Opt/Esc)+ Ctrl+ epoi Ctrl+ x+ e, che metterebbe tutto il file hosts su una riga e lo caricherebbe vim(probabilmente non è il miglior uso di queste funzionalità - tuttavia, l'utilità di questi metodi può essere estrapolata dai pochi esempi discussi Qui).

Nota che presumo che il tuo readlinesia impostato in emacsmodalità. Se readlineè impostata la vimmodalità, è possibile scoprire facilmente i collegamenti pertinenti utilizzando il comando:

bind -p

e alla ricerca di edit-and-execute-commando shell-expand-line, che erano rispettivamente associati alle associazioni Ctrl+ x+ ee Meta(Alt/Opt/Esc)+ Ctrl+ e.


Puoi dire a bash di usare le combinazioni di tasti vi invece di emacs. Utilizzare set -o viper accenderlo. Quindi puoi semplicemente usare la vmappatura in modalità normale per modificare il comando corrente nel tuo editor.
Quincy Bowers,

1
Sicuramente questo è un grande trucco per modificare la riga di comando usando vi ma ci sono almeno due problemi usando questo metodo per leggere il testo dallo stdin: 1. shell-expand-linerimuovere le nuove righe dal testo espanso e 2. edit-and-execute-commandprovare ad eseguire il comando scritto nel buffer , qualunque cosa venga salvata o meno, quando si esce da vi.
toro2k,

Woah, è fantastico. Imparo qualcosa di nuovo su readline ogni giorno, sembra ...
Doorknob,

2

In bash ho trovato utile usare la sostituzione di processo usando la <(command)sintassi, ad esempio:

vim <(echo This is example.)
vim <(cat /etc/hosts)

Guarda anche:


4
Nota che questo non funzionerà in tutte le shell. Credo che funzionerà solo in bashe zsh(e non sh, ksh,dash , fish, csh, tcsh, etc.)
Martin Tournoij

@Carpetsmoker Dovrebbe funzionare in ksh88 e versioni successive, penso, ma sì, la sostituzione del processo non è POSIX.
muru,

4
E fai attenzione a non ingannarti! Quando avvii Vim in questo modo, apre un buffer per un file simile/proc/PID/fd/FD . Se si scrive il buffer e si esce, Vim non si lamenta, ma il file su cui si è scritto verrà rimosso dal sistema operativo. Usando -come nome del file il buffer aperto non ha alcun file associato ad esso, quindi se provi ad uscire senza (fino a quando non usi un comando bang o simile) il salvataggio di Vim ti avviserà.
toro2k,

1
Questo è bello perché si generalizza bene vimdiff <(echo foo) <(echo bar).
mercoledì

@ toro2k Per seguire, sembra che usare :nexte:prev lo stream e non ottenga nulla. Vale anche la pena ricordare che i processi non sono paralleli tra loro - ad esempio le cat <(sleep 3; echo a) <(echo b)stampe in ordine - e mentre catinterleave scrive e legge, vimattende che il file "termini la lettura" prima di visualizzare tutto tranne il frame esterno.
Giovanni P

-1

Se l'utilizzo di una pipeline per un nuovo Vim non è un requisito, è possibile utilizzare la capacità di Vim di inserire l'output dei comandi nel buffer corrente, unitamente a un buffer con backup non di file (come con :newo modificare un file inesistente)

:read!cat /etc/hosts in modalità comando inserirà l'output nel buffer corrente sotto la posizione corrente del cursore.

Oltre a dover eliminare la prima riga vuota che rimane quando viene eseguita su un buffer vuoto, funziona bene ed è particolarmente utile se Vim è già in esecuzione.


1
Come risponde alla domanda?
Muru,

Prende l'output del comando e lo mette in vim.
ewatt,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.