On Unix and a few other systems you can also use backticks for the file name argument, for example: :next `find . -name ver\\*.c -print` :view `ls -t *.patch \| head -n1` The backslashes before the star are required to prevent the shell from expanding "ver*.c" prior to execution of the find program. The backslash before the shell pipe symbol "|" prevents Vim from parsing it as command termination.
If I type the command taken from the help, I get an error:
:next `find . -name ver\\*.c -print E79: Cannot expand wildcards
Why does the example from the help use two backslashes instead of one, and why does it not work?
The following work:
If I remove one of the two backslashes which protect the star from being expanded by the shell before the
:next `find . -name ver\*.c -print`
If I remove both of backslashes and put single quotes around the pattern
:next `find . -name 'ver*.c' -print`
Up to this point, the rule seems to be:
if your shell command contains a star and you don't want the shell to expand it before the command, put one backslash in front of it or put single quotes around the pattern.
But the help gives another example:
:view `ls -t *.patch \| head -n1`
This command works without any modification, no need of single quotes, no need of backslash.
I suppose the reason why it works is because the
ls command (contrary to the
-name argument of the
find command) accept multiple file arguments and sees no problem with the shell expanding
Now, let's say I want to look for all the files with the extension
.conf inside the
/etc folder and pipes the output of
grep to get only the matches containing the string
In the shell, from any working directory, I would type:
find /etc -name '*.conf' | grep input
And it would work.
In vim, I will type the same command putting backticks around it, and a backslash in front of the pipe symbol to prevent vim from interpreting it as a command termination :
:next `find /etc -name '*.conf' \| grep input`
And it works.
Now, if I type the same command without the pipe and the
grep input, I get an error:
:next `find /etc -name '*.conf'` E79: Cannot expand wildcards
Why is there an error in this case even though I protected the star with single quotes?
And why is there an error now, but not just before with the pipe and the
To try understanding, I've come up with a simpler command:
find . -name '*.conf'
It looks for all the files with the extension
.conf in the working directory. The command works in the shell.
To test it in vim, I typed:
:next `find . -name '*.conf'`
And it works. In this case the dot stands for my current working directory as displayed by the Ex command
:pwd which is my home directory
/home/username since I launched the vim session from it.
Why does it work when I ask to search in the current working directory whereas it doesn't work when I ask to search in an arbitrary folder such as
Now, if I change my working directory from
/etc with the vim Ex command
:cd /etc and retry the same command as before, again it errors out:
:next `find . -name '*.conf'` E79: Cannot expand wildcards
Why does the same command work when I'm in my home folder but not when I'm in
I'm sure there's some logic, but I can't find one.
What is the general and correct syntax to populate the arglist with an arbitrary shell command (containing a star, a pipe, searching in any directory from any working directory) ?
I'm using vim version 7.4.942 and zsh is my default shell.
I tested these commands with a minimum of initializations (
vim -u NORC -N) from bash as well as from zsh.
Do I need to configure vim to call bash and not zsh ?
vim $(find . -name ver*.c)
vim $(find . -name ver\*.c -print),
vim $(ls -t *.patch | head -n1),
vim $(find /etc -name '*.conf' | grep input),
vim $(find /etc -name '*.conf'),
vim $(find . -name '*.conf')
--remote, see: vi.stackexchange.com/a/5618/4939) but I'm curious to know how to do it directly from the current session. If it's not possible that's fine, but after reading the help it seems it can be done. If it is, I would like to understand why vim reacts so differently to similar commands.
find /etc -name '*.conf'not working, I’d think some funny names come out of that command, and, this may be the reason why it worked when piped through