I'm trying to search for the selected line of a file using the following:

function! GrepSelection()
    normal! gvy
    let result = escape(@", '\\/.*$^~[]#')
    let result = substitute(result, "\n$", "", "")
    let result = substitute(result, "\n", '\\n', "g")
    new | setlocal buftype=nofile bufhidden=hide noswapfile
    execute 'grep "'.result.'" file'
xnoremap <silent> <unique> * :<C-U>call GrepSelection()<CR>

but it seems it fail when i replace the execute part with read ! (it also fail with read!). Yet it does work when i do this manually on the commandline.

The way it fail is:

/bin/bash: grep ".result." file: No such file or directory

where it obviously does find the file, but the problem here is the fact that ".result." is taken literally, instead of being replaced with the selected string (like when execute is used instead).

Anything wrong with what I'm doing here?

  • You'll have to be more specific. How does it fail? Does it give an error, or does it just not do the correct thing? Sep 7, 2020 at 4:00
  • 1
    just added a brief explanation on how it fail (and nearly at the same time you commented) :) Sep 7, 2020 at 4:02
  • Yeah, i only tried with read !. Just tried with read! {cmd} but it doesn't seem to work and return the same error. Sep 7, 2020 at 4:09
  • 1
    yeah, already checked them but i wanted something a bit different. (which your solution helped to make) @filbranden Sep 7, 2020 at 4:25
  • 1
    Also consider you can do a lot of that in Vim itself. For example, the :v command (see :help :vglobal) can be used to delete lines not matching a pattern. So new | 0read file | v/pattern/d will get you a buffer with only the lines in file that match pattern... No need to run an external grep and interact with the shell!
    – filbranden
    Sep 7, 2020 at 4:28

1 Answer 1


You still need the execute, in order to interpolate the contents of the result Vimscript variable into the shell command:

execute 'read !grep "'.result.'" file'

Note that now this is a shell command and no longer just a Vim command, so consider using shellescape() to properly escape the string for use in a shell command. (But note that you may need to adapt the rest of the script for that to work correctly.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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