Sostituisci la selezione con l'output del comando esterno


10

Supponendo di avere una riga in un file con l' XXXXessere un segnaposto che ho selezionato vcome segue:

XXXX Some other text

Come posso cambiare solo la XXXXcon l'output di un comando esterno, come ad esempio date +%Y%m%d?

Sono arrivato fino a

:'<,'>!date +\%Y\%m\%d 

ma questo ha sostituito l'intera linea.


Questione connessa su StackOverflow: stackoverflow.com/q/8403599/...
Hotschke

Risposte:


15

È possibile eliminare il testo e inserire l'output di un comando utilizzando CtrlR- =:

CTRL-R {0-9a-z"%#*+:.-=}                                        i_CTRL-R
                Insert the contents of a register.  Between typing CTRL-R and
                the second character, '"' will be displayed to indicate that
                you are expected to enter the name of a register.
 …
                                                        i_CTRL-R_=
                        '='     the expression register: you are prompted to
                                enter an expression (see expression)

Per l'espressione, è possibile utilizzare la system()funzione per eseguire comandi esterni.

Dopo aver selezionato il testo, premere c, quindi <c-r>=e utilizzare system('date +%Y%m%d')come espressione.


1
Ciò aggiunge una nuova riga tra il testo sostituito e il resto della riga, non è vero?
muk.li,

2
@ muk.li che fa parte dell'output di date. Se provi qualcosa del genere system('printf %s foo'), che non genera una nuova riga finale, noterai che c'è una differenza.
muru,

4
@ muk.li se vuoi solo la data nel testo, c'è la strftimefunzione che puoi usare al posto di system('date …'). La stringa di formato è la stessa.
muru,

2
Non è necessario eliminare il testo selezionato. È possibile utilizzare "=system('date +%Y%m%d')pinvece la selezione visiva.
Hauleth,

5

Se si posiziona il cursore su tale linea è possibile:

  • 0 per posizionare il cursore nella prima colonna.
  • f Space per posizionare il cursore nel primo spazio vuoto.
  • i Enter Esc per dividere la linea.
  • l per spostare il cursore di una riga verso l'alto.
  • :.!date +\%Y\%m\%d per eseguire il comando.
  • J per unire nuovamente le linee.

Da :h :visual_example:

Attualmente il comando ":" funziona solo su intere righe. Quando selezioni parte di una riga, facendo qualcosa come ":! Date" sostituirai l'intera riga. Se si desidera sostituire solo parte della linea, è necessario creare una mappatura per essa. In una versione futura ":" potrebbe funzionare su linee parziali.

Vedi anche :h visual-operatorsper i dettagli.

Da questo commento: puoi anche provare il plugin vis o NrrwRgn . Entrambi dovrebbero gestirlo bene. (Grazie @ christian-brabandt per l'informazione).


2

Creare una mappatura temporanea per tali sostituzioni. Per esempio:

:vnoremap qq c<C-R>=system('wc -c | perl -pe chomp', @")<CR><ESC>

Quindi in modalità visiva è possibile selezionare il testo, digitare qqe verrà sostituito dal comando output. In questo esempio wc -celabora la selezione, che è il @"parametro. perl -pe chompè necessario per rimuovere una nuova riga finale dall'output.


1
Si noti che questa soluzione è un wrapper per la risposta di Muru, la creazione di una mappatura per un utilizzo una volta potrebbe non essere il metodo più efficiente.
statox

1

Prova questo:

:let @a = system('date +\%Y\%m\%d')[:-2]
:'<,'>g/XXXX/s/XXXX/\=@a/g
  • La prima riga salva l'output del datecomando nel registro a, con la nuova riga finale rimossa.
  • La seconda riga controlla a livello globale la selezione e segna le righe contenenti XXXX( g/XXXX/) e
  • sostituire tutte le istanze di XXXXcon il contenuto del registro a ( s/XXXX/\=@a/g)

Vedi :h let-@e :h :globalanche la sezione "Sublist" in:h list-index


0

Plugin: Visual Block Commands (vis) di DrChip

Installazione vis.vba.gze dipendenza cecutil.vba.gzin packpath vim8

# shell brace expansion (bash >=3.0, zsh>=2.6)
$ mkdir -p ~/.vim/pack/manual/start/{vis,cecutil}
$ vim http://www.drchip.org/astronaut/vim/vbafiles/vis.vba.gz
:UseVimball ~/.vim/pack/manual/start/vis
:e http://www.drchip.org/astronaut/vim/vbafiles/cecutil.vba.gz
:UseVimball ~/.vim/pack/manual/start/cecutil

L'esempio OP diventa

:'<,'>B !date +\%Y\%m\%d 
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.