10

Assuming I have a line in a file with XXXX being a placeholder I have selected via v as follows:

XXXX Some other text

How can I change only the XXXX with the output of an external command, such as date +%Y%m%d?

I got as far as

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

but that replaced the whole line.

15

You could delete the text and insert the output of a command using 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)

For the expression, you can use the system() function to run external commands.

After selecting the text, press c, then <c-r>= and use system('date +%Y%m%d') as the expression.

| improve this answer | |
  • 1
    That adds a newline between the replaced text and the rest of the line, doesn't it? – muk.li Apr 17 '16 at 20:10
  • 2
    @muk.li that's part of the output of date. If you try something like system('printf %s foo'), which doesn't output a trailing newline, you'll see there's a difference. – muru Apr 17 '16 at 20:12
  • 4
    @muk.li if you just want the date in the text, there's the strftime function which you can use instead of system('date …'). The format string is the same. – muru Apr 17 '16 at 20:27
  • 2
    You do not need to delete selected text. You can use "=system('date +%Y%m%d')p on visual selection instead. – Hauleth Apr 18 '16 at 8:03
5

If you put the cursor on such a line you can:

  • 0 to put the cursor in the first column.
  • f Space to put the cursor in the first blank.
  • i Enter Esc to split the line.
  • l to move the cursor one line up.
  • :.!date +\%Y\%m\%d to execute the command.
  • J to join the lines again.

From :h :visual_example:

Currently the ":" command works on whole lines only. When you select part of a line, doing something like ":!date" will replace the whole line. If you want only part of the line to be replaced you will have to make a mapping for it. In a future release ":" may work on partial lines.

See also :h visual-operators for details.

From this comment: You can also try the vis or NrrwRgn plugin. Both should handle it just fine. (Thanks @christian-brabandt for the tip).

| improve this answer | |
2

Create a temporary mapping for such replacements. For example:

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

Then in visual mode you can select text, type qq and it'll be replaced by the command output. In this example wc -c will process your selection, which is the @" parameter. perl -pe chomp is needed to remove a trailing newline from the output.

| improve this answer | |
  • 1
    Note that this solution is a wrapper around muru's answer, creating a mapping for a one time usage might not be the most efficient method. – statox Nov 13 '18 at 16:06
1

Try this:

:let @a = system('date +\%Y\%m\%d')[:-2]
:'<,'>g/XXXX/s/XXXX/\=@a/g
  • The first line saves the output of date command into register a, with the ending newline removed.
  • The second line globally inspect your selection and mark the lines containing XXXX (g/XXXX/), and
  • replace all the instances of the XXXX with the content of register a (s/XXXX/\=@a/g)

See :h let-@ and :h :global as well as the "Sublist" section in :h list-index

| improve this answer | |
0

Plugin: Visual Block Commands (vis) by DrChip

Installation of vis.vba.gz and dependency cecutil.vba.gz into 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

OP example becomes

:'<,'>B !date +\%Y\%m\%d 
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.