Из справки :help backtick-expansion
:
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.
Если я наберу команду, взятую из справки, я получу ошибку:
:next `find . -name ver\\*.c -print
E79: Cannot expand wildcards
Почему пример из справки использует две обратных косых черты вместо одной, и почему это не работает?
Следующая работа:
Если я удалю одну из двух обратных косых черт, которые защищают звезду от расширения оболочкой перед
find
программой::next `find . -name ver\*.c -print`
Если я удаляю оба обратных слеша и ставлю одинарные кавычки вокруг шаблона
ver*.c
::next `find . -name 'ver*.c' -print`
До этого момента казалось, что правило таково:
если ваша команда оболочки содержит звездочку, и вы не хотите, чтобы оболочка расширяла ее перед командой, поместите перед ней одну обратную косую черту или заключите в кавычки шаблон .
Но помощь дает другой пример:
:view `ls -t *.patch \| head -n1`
Эта команда работает без каких-либо изменений, не нужно использовать одинарные кавычки, не нужно использовать обратную косую черту.
Я полагаю, что причина этого в том, что ls
команда (в отличие от -name
аргумента find
команды) принимает несколько аргументов файла и не видит проблем с расширением оболочки *.patch
.
Теперь, скажем, я хочу найти все файлы с расширением .conf
внутри /etc
папки и направить выходные данные find
в, grep
чтобы получить только совпадения, содержащие строку input
.
В командной строке из любого рабочего каталога я набрал бы:
find /etc -name '*.conf' | grep input
И это будет работать.
В vim я наберу ту же команду, поставив вокруг нее обратные черты и обратную косую черту перед символом канала, чтобы vim не интерпретировал ее как завершение команды:
:next `find /etc -name '*.conf' \| grep input`
И это работает.
Теперь, если я ввожу ту же команду без канала и grep input
, я получаю ошибку:
:next `find /etc -name '*.conf'`
E79: Cannot expand wildcards
Почему в этом случае возникает ошибка, хотя я защищал звезду одинарными кавычками?
И почему сейчас ошибка, а не только раньше с трубкой и grep input
?
Чтобы понять, я придумал более простую команду:
find . -name '*.conf'
Он ищет все файлы с расширением .conf
в рабочем каталоге. Команда работает в оболочке.
Чтобы проверить это в vim, я набрал: :next `find . -name '*.conf'`
И это работает. В этом случае точка обозначает мой текущий рабочий каталог, отображаемый командой Ex, :pwd
которая является моим домашним каталогом, /home/username
так как я запустил с него сеанс vim.
Почему это работает, когда я запрашиваю поиск в текущем рабочем каталоге, тогда как он не работает, когда я запрашиваю поиск в произвольной папке, такой как /etc
?
Теперь, если я изменил свой рабочий каталог с /home/username
на /etc
команду vim Ex :cd /etc
и повторил ту же команду, что и раньше, снова произойдет ошибка:
:next `find . -name '*.conf'`
E79: Cannot expand wildcards
Почему та же команда работает, когда я нахожусь в моей домашней папке, а не когда я нахожусь в /etc
?
Я уверен, что есть какая-то логика, но я не могу найти.
Что общее и правильный синтаксис для заполнения списка аргументов с произвольной командой оболочки (содержащей звезду, трубу, поиск в любой директории из любого рабочего каталога)?
Я использую Vim версии 7.4.942 и ЗШ моя оболочка по умолчанию. Я проверил эти команды с минимумом инициализаций ( vim -u NORC -N
) из Баша, а также из 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
см .: vi.stackexchange.com/a/5618/4939 ), но мне любопытно узнать, как сделать это прямо из текущей сессии. Если это невозможно, это нормально, но после прочтения справки кажется, что это можно сделать. Если это так, я хотел бы понять, почему vim так по-разному реагирует на подобные команды.find /etc -name '*.conf'
неработоспособности, я думаю, некоторые забавные имена появляются из этой команды, и это может быть причиной того, почему она сработала, когда прошла по каналуgrep
.Ответы:
Я до сих пор не знаю, как использовать расширение backtick для заполнения arglist произвольной командой оболочки, однако я нашел обходной путь.
От
:help `=
:Таким образом, вместо непосредственного расширения команды оболочки, например:
Мы можем отправить команду оболочки в функцию Vim
systemlist()
и использовать регистр выражений=
для расширения полученного выражения следующим образом:Чтобы сохранить некоторые нажатия клавиш, я определил следующую команду Ex в моем vimrc (
:PA
для Populate Arglist):И проверил это с помощью различных команд оболочки:
Пока он работает как ожидалось, и команда может быть набрана так, как это было бы в оболочке (например, не нужно выходить из канала).
Это кажется более последовательным и надежным, чем прямое обратное расширение.
источник