How can I pipe the output of a shell command into a new buffer in Vim? The following obviously wouldn't work, but you can see what I'm getting at:

:!echo % | :newtab

You can't pipe the output of a shell command into a command that creates a new buffer, but you can create a new buffer and read the output of a shell command into that buffer with one entry on Vim's command line. A working version of your example would be

:tabnew | r !echo <c-r>=bufname("#")<cr>

Note that the pipe symbol in this case is a separator between Vim ex commands, not the shell's pipe. See also

:help :tabnew
:help :r!
:help :bar
  • That's almost exactly what I need, just the other way around so that I can access the filename of the current buffer. Note: updated the question to hopefully clarify the desired end result. Jun 29 '10 at 6:44
  • @Richard Marquez: i updated this answer. the new tab is now opened with the "old" filename, thus you could call :!echo %
    – akira
    Jun 29 '10 at 8:24
  • But not :r!echo without altering the buffer. Jun 29 '10 at 9:27
  • 2
    @garyjohn, akira: thanks for the help. The "<c-r>=..." part made Vim spew errors, but I was able to get it working with ":tabnew | r !echo #". Jun 29 '10 at 14:22
  • 1
    Might also be useful to note that if you want to map this to a key in your .vimrc, you'll need to replace the | character with <bar>. Jun 29 '10 at 18:15

Here's what I do. It's alluded to in comments in the above answers.

:new | r ! <cmd>
:new | r ! <cmd> #   (# is replaced with filename)

Example 1: Find all text files in /tmp

:new | r ! find /tmp -name '*.txt'

Example 2: You're editing file foo.txt and you want to run ls -la foo.txt and get the output in a buffer:

:new | r ! ls -la #

The # is replaced with the filename of the original buffer you're editing. This is particularly useful for ad-hoc source control commands e.g.

:new | r ! hg annotate -un #

:new creates a horizontal split, use :vnew if you want a vertical split instead and :tabnew for a new tab.

  • Are you able to answer this question here as well? it is about trying to use the current buffer with % for the next buffer but E499.
    – hhh
    Jul 20 '17 at 19:28
:tabnew | enew | r ! <your shell cmd>

works for me.


If you really require to store the result in a new buffer, but require info from the old current buffer, then you can either use system():

:let res = system('echo '.expand('%'))

or store the current buffer name for later:

:let bn = expand('%')
:tabnew | :r!echo <c-r>=bn<cr>
  • see the other answer, you can do it without storing the name in a variable. but good answer anyway.
    – akira
    Jun 29 '10 at 11:12
  • Indeed. I wasn't sure '#' will give the expected result in that case -- as I never use tabs Jun 29 '10 at 12:42

@Ciro Santilli linked the answer https://stackoverflow.com/a/3826018/9306292

:enew | .! <command>

If you want to keep your configuration simple, use one of those:

<C-w>v / <C-w>s / yourtabkeybinding, ie <C-w>t

and then


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.