De l'aide :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 je tape la commande tirée de l'aide, j'obtiens une erreur:
:next `find . -name ver\\*.c -print
E79: Cannot expand wildcards
Pourquoi l'exemple de l'aide utilise-t-il deux barres obliques inverses au lieu d'une, et pourquoi cela ne fonctionne-t-il pas?
Le travail suivant:
Si je supprime l'une des deux barres obliques inverses qui protègent l'étoile d'être étendue par le shell avant le
find
programme::next `find . -name ver\*.c -print`
Si je supprime les deux barres obliques inverses et place des guillemets simples autour du motif
ver*.c
::next `find . -name 'ver*.c' -print`
Jusqu'à présent, la règle semble être la suivante:
si votre commande shell contient une étoile et que vous ne voulez pas que le shell la développe avant la commande, placez une barre oblique inverse devant elle ou mettez des guillemets simples autour du motif .
Mais l'aide donne un autre exemple:
:view `ls -t *.patch \| head -n1`
Cette commande fonctionne sans aucune modification, pas besoin de guillemets simples, pas besoin de barre oblique inverse.
Je suppose que la raison pour laquelle cela fonctionne est que la ls
commande (contrairement à l' -name
argument de la find
commande) accepte plusieurs arguments de fichier et ne voit aucun problème avec l'expansion du shell *.patch
.
Maintenant, disons que je veux rechercher tous les fichiers avec l'extension .conf
dans le /etc
dossier et redirige la sortie de find
vers grep
pour obtenir uniquement les correspondances contenant la chaîne input
.
Dans le shell, à partir de n'importe quel répertoire de travail, je tape:
find /etc -name '*.conf' | grep input
Et ça marcherait.
Dans vim, je vais taper la même commande en le mettant en arrière et une barre oblique inverse devant le symbole du tuyau pour empêcher vim de l'interpréter comme une terminaison de commande:
:next `find /etc -name '*.conf' \| grep input`
Et il fonctionne.
Maintenant, si je tape la même commande sans le pipe et le grep input
, j'obtiens une erreur:
:next `find /etc -name '*.conf'`
E79: Cannot expand wildcards
Pourquoi y a-t-il une erreur dans ce cas même si j'ai protégé l'étoile avec des guillemets simples?
Et pourquoi y a-t-il une erreur maintenant, mais pas juste avant avec le tuyau et le grep input
?
Pour essayer de comprendre, j'ai trouvé une commande plus simple:
find . -name '*.conf'
Il recherche tous les fichiers avec l'extension .conf
dans le répertoire de travail. La commande fonctionne dans le shell.
Pour le tester dans vim, j'ai tapé: :next `find . -name '*.conf'`
Et ça marche. Dans ce cas, le point représente mon répertoire de travail actuel tel qu'affiché par la commande Ex :pwd
qui est mon répertoire personnel /home/username
depuis que j'ai lancé la session vim à partir de celui-ci.
Pourquoi ça marche quand je demande de chercher dans le répertoire de travail courant alors que ça ne marche pas quand je demande de chercher dans un dossier arbitraire comme /etc
?
Maintenant, si je change mon répertoire de travail de en /home/username
à l' /etc
aide de la commande vim Ex :cd /etc
et réessaye la même commande qu'avant, encore une fois il se trompe:
:next `find . -name '*.conf'`
E79: Cannot expand wildcards
Pourquoi la même commande fonctionne-t-elle lorsque je suis dans mon dossier de départ mais pas quand je le suis /etc
?
Je suis sûr qu'il y a une certaine logique, mais je n'en trouve pas.
Quelle est la syntaxe générale et correcte pour remplir l'arglist avec une commande shell arbitraire (contenant une étoile, un canal, la recherche dans n'importe quel répertoire depuis n'importe quel répertoire de travail)?
J'utilise la version 7.4.942 de vim et zsh est mon shell par défaut. Je l' ai testé ces commandes avec un minimum de initialisations ( vim -u NORC -N
) de bash, ainsi que de zsh.
Dois-je configurer vim pour appeler bash et non zsh?
la source
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
, voir: vi.stackexchange.com/a/5618/4939 ) mais je suis curieux de savoir comment faites-le directement à partir de la session en cours. Si ce n'est pas possible, c'est bien, mais après avoir lu l'aide, il semble que cela puisse être fait. Si c'est le cas, j'aimerais comprendre pourquoi vim réagit si différemment à des commandes similaires.find /etc -name '*.conf'
ne pas fonctionner, je pense que certains noms drôles sortent de cette commande, et c'est peut-être la raison pour laquelle cela a fonctionné une fois redirigégrep
.Réponses:
Je ne sais toujours pas comment utiliser backtick-expansion pour remplir l'arglist avec une commande shell arbitraire, mais j'ai trouvé une solution de contournement.
De
:help `=
:Ainsi, au lieu d'étendre directement une commande shell comme celle-ci:
Nous pouvons envoyer la commande shell à la fonction Vim
systemlist()
et utiliser le registre d'expression=
pour développer l'expression résultante comme ceci:Pour enregistrer certaines séquences de touches, j'ai défini la commande Ex suivante dans mon vimrc (
:PA
pour Populate Arglist):Et je l'ai testé avec diverses commandes shell:
Jusqu'à présent, cela fonctionne comme prévu et la commande peut être tapée comme elle le serait dans le shell (pas besoin d'échapper au pipe par exemple).
Il semble plus cohérent et fiable que l'expansion directe en backtick.
la source