De ayuda :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.
Si escribo el comando tomado de la ayuda, aparece un error:
:next `find . -name ver\\*.c -print
E79: Cannot expand wildcards
¿Por qué el ejemplo de la ayuda usa dos barras invertidas en lugar de una y por qué no funciona?
El siguiente trabajo:
Si elimino una de las dos barras diagonales inversas que evitan que la estrella se expanda antes del
find
programa::next `find . -name ver\*.c -print`
Si elimino ambas barras invertidas y pongo comillas simples alrededor del patrón
ver*.c
::next `find . -name 'ver*.c' -print`
Hasta este punto, la regla parece ser:
si su comando de shell contiene una estrella y no desea que el shell lo expanda antes del comando, coloque una barra invertida frente a él o ponga comillas simples alrededor del patrón .
Pero la ayuda da otro ejemplo:
:view `ls -t *.patch \| head -n1`
Este comando funciona sin ninguna modificación, sin necesidad de comillas simples, sin necesidad de barra invertida.
Supongo que la razón por la que funciona es porque el ls
comando (al contrario del -name
argumento del find
comando) acepta múltiples argumentos de archivo y no ve ningún problema con la expansión del shell *.patch
.
Ahora, digamos que yo quiero para buscar todos los archivos con la extensión .conf
dentro de la /etc
carpeta y canaliza el resultado de find
que grep
para obtener sólo los partidos que contienen la cadena input
.
En el shell, desde cualquier directorio de trabajo, escribiría:
find /etc -name '*.conf' | grep input
Y funcionaría.
En vim, escribiré el mismo comando poniendo marcas de retroceso a su alrededor, y una barra invertida frente al símbolo de tubería para evitar que vim lo interprete como una terminación de comando:
:next `find /etc -name '*.conf' \| grep input`
Y funciona.
Ahora, si escribo el mismo comando sin la tubería y el grep input
, obtengo un error:
:next `find /etc -name '*.conf'`
E79: Cannot expand wildcards
¿Por qué hay un error en este caso a pesar de que protegí la estrella con comillas simples?
¿Y por qué hay un error ahora, pero no solo antes con la tubería y el grep input
?
Para intentar comprender, he creado un comando más simple:
find . -name '*.conf'
Busca todos los archivos con la extensión .conf
en el directorio de trabajo. El comando funciona en el shell.
Para probarlo en vim, escribí: :next `find . -name '*.conf'`
Y funciona. En este caso, el punto representa mi directorio de trabajo actual como lo muestra el comando Ex, :pwd
que es mi directorio de inicio /home/username
desde que inicié la sesión vim desde él.
¿Por qué funciona cuando solicito buscar en el directorio de trabajo actual, mientras que no funciona cuando solicito buscar en una carpeta arbitraria como /etc
?
Ahora, si cambio mi directorio de trabajo de /home/username
a /etc
con el comando vim Ex :cd /etc
y reintento el mismo comando que antes, nuevamente se produce un error:
:next `find . -name '*.conf'`
E79: Cannot expand wildcards
¿Por qué funciona el mismo comando cuando estoy en mi carpeta de inicio pero no cuando estoy dentro /etc
?
Estoy seguro de que hay algo de lógica, pero no puedo encontrar una.
¿Cuál es la sintaxis general y correcta para llenar el arglista con un comando de shell arbitrario (que contiene una estrella, una tubería, buscando en cualquier directorio desde cualquier directorio de trabajo)?
Estoy usando la versión vim 7.4.942 y zsh es mi shell predeterminado. Probé estos comandos con un mínimo de inicializaciones ( vim -u NORC -N
) tanto de bash como de zsh.
¿Necesito configurar vim para llamar a bash y no a zsh?
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
, ver: vi.stackexchange.com/a/5618/4939 ) pero tengo curiosidad por saber cómo hazlo directamente desde la sesión actual. Si no es posible, está bien, pero después de leer la ayuda, parece que se puede hacer. Si es así, me gustaría entender por qué vim reacciona de manera tan diferente a comandos similares.
find /etc -name '*.conf'
no funcione, creo que algunos nombres divertidos salen de ese comando, y esta puede ser la razón por la que funcionó cuando se transmitió grep
.
vim $(find . -name ver*.c)