126

I am trying to redirect the output of a bash command into a new file.

If I try the pipe as below :

ls -la | vim

Bash shows me the errors :

Vim: Error reading input, exiting...
Vim: preserving files...
Vim: Finished.

I know that I can open Vim and then use :

:r !ls -la

But is there a way to do this in bash itself, so that Vim is opened and the output is pasted there automatically?

muru
  • 193,181
  • 53
  • 473
  • 722
faizal
  • 2,927
  • 10
  • 23
  • 27

7 Answers7

203

You can use process substitution (this also works with applications that can't read from STDIN):

vim <(ls -la)

Or use vim's function to read from STDIN:

ls -la | vim -
muru
  • 193,181
  • 53
  • 473
  • 722
chaos
  • 27,106
  • 12
  • 74
  • 77
  • 4
    `<(ls -la)` is actually [process substitution](https://gnu.org/software/bash/manual/bash.html#Process-Substitution) rather than [command substitution](https://gnu.org/software/bash/manual/bash.html#Command-Substitution). – Eliah Kagan Sep 02 '14 at 01:32
  • 3
    I really like vim's option, it allows me to search, find and save the output easily from data dumps. – Josue Alexander Ibarra May 11 '16 at 21:36
  • vim will warn of your buffer is not saved. You may pass `-R` or `-c "setlocal buftype=nofile bufhidden=hide noswapfile"` to avoid this. – Jérôme Pouiller Dec 11 '20 at 12:24
  • This question/answer is the closest to what I've been trying to search on SO, but if anyone can help me: Is it possible to be using a shell (ie bash), and then turn my current shell buffer (ie, everything above my cursor) into a doc I can temp edit in vim? Even read only? For example `ls somdir/` and then after it dumps output, i can search and yank from it? Much appreciated!!! – Evan Morrison Jan 28 '21 at 06:17
  • @EvanMorrison This is a good question, why not [asking](https://askubuntu.com/questions/ask) it? – chaos Jan 28 '21 at 06:27
  • @chaos Thanks, [I did](https://askubuntu.com/questions/1311906/using-terminal-buffer-as-context-for-vim):) – Evan Morrison Jan 29 '21 at 06:29
  • @EvanMorrison I know that hitting `v` while typing a command in bash brings up the command in `vim`. But just the command... – Tom Russell Feb 28 '21 at 20:49
  • Entering the command `ls -la | vim` in bash results in `Vim: Warning: Input is not from a terminal` and `vim` just exits. But `vim <(ls -la)` works for me As does its `gvim` analog. – Tom Russell Feb 28 '21 at 20:50
  • @TomRussell You need the `-` (minus) after the command to tell vim to read from the stdin. – chaos Feb 28 '21 at 23:02
  • @chaos I see my error. Thanks! – Tom Russell Mar 01 '21 at 06:58
  • Is there a way to make this the default behavior for certain git commands? I have my .zshrc set up to open man pages in vim by default, for example. – Aaron Parisi Jul 20 '22 at 18:16
55

You're really close on your own. You were just missing one character.

ls -la | vim -
Cris Holdorph
  • 889
  • 1
  • 7
  • 9
25

Here's another approach, hopefully to teach someone something new.

If you know that the command :r !ls -la works inside vim, you can do the following to open vim and make it run the command as soon as it opens, straight from bash:

vim -c ':r! ls -la'

This is the equivalent of opening vim then executing the command :r! ls -la. This should work with any vim command, where the command comes after the -c option.

Alaa Ali
  • 31,075
  • 11
  • 94
  • 105
  • I like it. This results in a little cleaner launch of `vim` on my system (doesn't hang the `bash` terminal) but results in the output from `git diff` missing syntax highlighting. This may be a particularity of my system. – Tom Russell Mar 01 '21 at 07:14
  • I meant, cleaner launch of `gvim`... And `bash` comes back with a carriage return. – Tom Russell Mar 01 '21 at 07:57
15

You can tell vim to open stdin:

ls -la | vim -
iffy
  • 1,117
  • 1
  • 8
  • 12
1

I would like to add an option

ls -al | view -

view is a read-only version of vim(equivalent to vim -R)

1

setlocal buftype=nofile

This is a good option if you are going to create an alias to replace less:

seq 100 | vim +':setlocal buftype=nofile' -

Now you don't need to type the ! to quit.

Another option is:

seq 100 | vim +'nnoremap q :quit!' -

so you can exit with just q<enter>.

Ciro Santilli OurBigBook.com
  • 26,663
  • 14
  • 108
  • 107
1

If your goal is simply to get the output into a text file then you don't need to invoke vim. Bash can do it alone with

ls -la > outputfile.txt