Remplacer la sélection par la sortie d'une commande externe

10

En supposant que j'ai une ligne dans un fichier avec XXXXun espace réservé que j'ai sélectionné via vcomme suit:

XXXX Some other text

Comment puis-je changer uniquement le XXXXavec la sortie d'une commande externe, comme date +%Y%m%d?

Je suis allé aussi loin que

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

mais cela a remplacé toute la ligne.

muk.li
la source
Question connexe sur stackoverflow: stackoverflow.com/q/8403599/…
Hotschke

Réponses:

15

Vous pouvez supprimer le texte et insérer la sortie d'une commande en utilisant 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)

Pour l'expression, vous pouvez utiliser la system()fonction pour exécuter des commandes externes.

Après avoir sélectionné le texte, appuyez sur c, puis <c-r>=et utilisez system('date +%Y%m%d')comme expression.

muru
la source
1
Cela ajoute une nouvelle ligne entre le texte remplacé et le reste de la ligne, n'est-ce pas?
muk.li
2
@ muk.li qui fait partie de la sortie de date. Si vous essayez quelque chose comme system('printf %s foo'), qui ne produit pas de nouvelle ligne de fin, vous verrez qu'il y a une différence.
muru
4
@ muk.li si vous voulez juste la date dans le texte, il y a la strftimefonction que vous pouvez utiliser à la place system('date …'). La chaîne de format est la même.
muru
2
Vous n'avez pas besoin de supprimer le texte sélectionné. Vous pouvez utiliser "=system('date +%Y%m%d')pla sélection visuelle à la place.
Hauleth
5

Si vous placez le curseur sur une telle ligne, vous pouvez:

  • 0 pour placer le curseur dans la première colonne.
  • f Space pour placer le curseur dans le premier blanc.
  • i Enter Esc pour diviser la ligne.
  • l pour déplacer le curseur d'une ligne vers le haut.
  • :.!date +\%Y\%m\%d pour exécuter la commande.
  • J pour rejoindre les lignes à nouveau.

De :h :visual_example:

Actuellement, la commande ":" ne fonctionne que sur des lignes entières. Lorsque vous sélectionnez une partie d'une ligne, faire quelque chose comme ":! Date" remplacera la ligne entière. Si vous souhaitez qu'une partie seulement de la ligne soit remplacée, vous devrez faire un mappage pour elle. Dans une future version, ":" pourrait fonctionner sur des lignes partielles.

Voir aussi :h visual-operatorspour plus de détails.

De ce commentaire: Vous pouvez également essayer le plugin vis ou NrrwRgn . Les deux devraient le gérer très bien. (Merci @ christian-brabandt pour l'astuce).

Jair López
la source
2

Créez un mappage temporaire pour ces remplacements. Par exemple:

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

Ensuite, en mode visuel, vous pouvez sélectionner du texte, taper qqet il sera remplacé par la sortie de la commande. Dans cet exemple wc -c, traitera votre sélection, qui est le @"paramètre. perl -pe chompest nécessaire pour supprimer une nouvelle ligne de fin de la sortie.

Oleg Tsybulskyi
la source
1
Notez que cette solution est un wrapper autour de la réponse de muru, la création d'un mappage pour une utilisation unique pourrait ne pas être la méthode la plus efficace.
statox
1

Essaye ça:

:let @a = system('date +\%Y\%m\%d')[:-2]
:'<,'>g/XXXX/s/XXXX/\=@a/g
  • La première ligne enregistre la sortie de la datecommande dans le registre a, avec la nouvelle ligne de fin supprimée.
  • La deuxième ligne inspecte globalement votre sélection et marque les lignes contenant XXXX( g/XXXX/), et
  • remplacer toutes les instances de la XXXXpar le contenu du registre a ( s/XXXX/\=@a/g)

Voir :h let-@et :h :globalainsi que la section "Sous-liste" dans:h list-index

Charles Jie
la source
0

Plugin: Visual Block Commands (vis) par DrChip

Installation vis.vba.gzet dépendance cecutil.vba.gzdans vim8 packpath

# 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'exemple OP devient

:'<,'>B !date +\%Y\%m\%d 
Hotschke
la source