73

I'm using grep -e Peugeot -e PeuGeot carlist.txt to search through carlist.txt and pull out some items and I presumed that grep -e Peugeot -e PeuGeot carlist.txt | vi would pipe it through for me but this is what I get:

Vim: Warning: Input is not from a terminal
Vim: Error reading input, exiting...
Vim: preserving files...
Vim: Finished.
4
  • if you want to include it in a file, I'd first use vi on the file, and then : :read !grep -e Peugeot -e PeuGeot carlist.txt . :read !cmd... will include the output of cmd... in the file (at the cursor's location) Nov 21, 2013 at 17:13
  • It's not clear what you mean by a "vi file". If you want the output to go into a file, use grep ... > /tmp/foo. You can add && vi /tmp/foo on the end if you want to edit that file immediately.
    – LarsH
    Nov 21, 2013 at 18:29
  • 1
    In fact there's no such thing as a "vi file". vi operates on arbitrary text files; the files themselves are not directly associated with vi. (Or, as I just learned, vi - will cause vi to operate on the contents of stdin; vim does this, but not all versions of vi do.) Nov 21, 2013 at 19:45
  • Related: How to edit content from the standard input? at Vim SE
    – kenorb
    Feb 19, 2015 at 13:06

6 Answers 6

129

Running vi or vim with '-' as an argument makes it read the file to edit from standard input. Hence:

grep -e Peugeot -e PeuGeot carlist.txt | vi -

will do what you need.

5
  • 4
    For anyone seeing this, attention: it expects from stdin. In some cases you'll have to redirect from stderr to stdin, e.g: valgrind my_file.out 2>&1 | vi -
    – Ciro Costa
    Sep 30, 2015 at 3:08
  • This removes search highlightings Nov 6, 2016 at 9:28
  • 6
    @MD.MohiuddinAhmed, how do you expect to keep grep's search coloring (composed of nonprintable characters) inside of Vim? You can always just do a search in Vim.
    – Wildcard
    Nov 15, 2016 at 6:25
  • I thought we can go with vim.org/scripts/script.php?script_id=302 plugin within vim. Nov 15, 2016 at 13:20
  • This answer is not quite accurate. You are piping to vim here, not vi. vi does not accept stdin. You can confirm it is vim by opening your "vi" and then :version
    – Kajukenbo
    Oct 13, 2021 at 1:23
17

Apart of vim -, you can also use process substitution using the <(command) syntax, in example:

vim <(echo This is example.)
vim <(cat /etc/hosts)

See also:

12

You should use output redirection:

grep ... > newfile.txt && vi newfile.txt

Also, I think your grep can be improved:

grep 'Peu[gG]eot' carlist.txt > newfile.txt && vi newfile.txt
0
6

Output redirection can also be used like this:

vi <(grep ...)

Even multiple command outputs can be redirected, as if they were saved in separate files:

vim -d <(ls) <(ls -a)
1

In ~/bin/r:

#!/bin/sh
[ $# -eq 0 ] && set -- -;
exec vi -R "$@"

in ~/.vimrc:

:  au StdinReadPost * set buftype=nofile

Then:

ls |r
grep -e Peugeot -e PeuGeot carlist.txt | r

and I've got

r- () { "$@" | r; }

in my ~/.bashrc, so

r- ls -l
1
  • This requires explanation. What the hell is going on here ? Nov 29, 2021 at 10:24
0

There are many effective ways to do what you want, either within vi(m) or outside vi(m).

Run your command, produce a (temporary) file, then edit the file (see Joseph R.'s answer)

grep -e"Peu[gG]eot" carlist.txt && vi /tmp/peugeot.txt

Run your command (in the background) to produce a temporary file, and edit the file, using ":e!" to refresh your file as it is produced (this is useful for logfiles, and other files being produced by another process, e.g. cron?),

grep -e "Peu[gG]eot" carlist.txt > /tmp/peugeot.txt &
vi /tmp/peugeot.txt

Run vi(m), and run a child process to create the temporary file, and then read it,

vi
:!grep -e "Peu[gG]eot" carlist.txt > /tmp/peugeot.txt
:r /tmp/peugeot.txt

Or, just switch to the file,

:e /tmp/peugeot.txt

Run vi(m), and use the double-bang "!!" to have vi run the child command, taking the results and inserting them into the current location (overwrites the current line, so make sure you have a blank line),

vi
i
here
empty
there
<esc>
kk
!!grep -e "Peu[gG]eot" carlist.txt

And now you can write the file (if you want to) to any filename,

:w /tmp/someotherfilename.txt

And Petr Uzel's answer is also good,

grep -e "Peu[gG]eot" carlist.txt | vi -

Which reads from stdin

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .