Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
share|improve this question

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
share|improve this answer
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. – Richard Marquez 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. – Luc Hermitte Jun 29 '10 at 9:27
@Luc Hermitte: right, i ll rollback. – akira Jun 29 '10 at 11:04
@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 #". – Richard Marquez Jun 29 '10 at 14:22

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.

share|improve this answer
:tabnew | enew | r ! <your shell cmd>

works for me.

share|improve this answer

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>
share|improve this answer
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 – Luc Hermitte Jun 29 '10 at 12:42

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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