Dall'aiuto :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.
Se digito il comando preso dall'aiuto, ricevo un errore:
:next `find . -name ver\\*.c -print
E79: Cannot expand wildcards
Perché l'esempio della guida utilizza due barre rovesciate anziché una e perché non funziona?
Il seguente lavoro:
Se rimuovo una delle due barre rovesciate che proteggono la stella dall'espansione della shell prima del
find
programma::next `find . -name ver\*.c -print`
Se rimuovo entrambe le barre rovesciate e inserisco virgolette singole attorno al modello
ver*.c
::next `find . -name 'ver*.c' -print`
Fino a questo punto, la regola sembra essere:
se il comando della shell contiene una stella e non si desidera che la shell la espanda prima del comando, mettere una barra rovesciata davanti o inserire virgolette singole attorno al modello .
Ma l'aiuto fornisce un altro esempio:
:view `ls -t *.patch \| head -n1`
Questo comando funziona senza alcuna modifica, senza bisogno di virgolette singole, senza necessità di barra rovesciata.
Suppongo che il motivo per cui funziona è perché il ls
comando (contrariamente -name
all'argomento del find
comando) accetta più argomenti di file e non vede alcun problema con l'espansione della shell *.patch
.
Ora, diciamo che voglio cercare tutti i file con l'estensione .conf
all'interno della /etc
cartella e convoglia l'output di find
to grep
per ottenere solo le corrispondenze contenenti la stringa input
.
Nella shell, da qualsiasi directory di lavoro, digitare:
find /etc -name '*.conf' | grep input
E funzionerebbe.
In vim, digiterò lo stesso comando inserendovi backtick e una barra rovesciata davanti al simbolo della pipe per impedire a vim di interpretarlo come terminazione del comando:
:next `find /etc -name '*.conf' \| grep input`
E funziona
Ora, se digito lo stesso comando senza pipe e il grep input
, ottengo un errore:
:next `find /etc -name '*.conf'`
E79: Cannot expand wildcards
Perché c'è un errore in questo caso anche se ho protetto la stella con virgolette singole?
E perché ora c'è un errore, ma non solo prima con la pipe e il grep input
?
Per provare a capire, ho escogitato un comando più semplice:
find . -name '*.conf'
Cerca tutti i file con l'estensione .conf
nella directory di lavoro. Il comando funziona nella shell.
Per testarlo in vim, ho scritto: :next `find . -name '*.conf'`
E funziona. In questo caso il punto indica la mia directory di lavoro corrente, come visualizzato dal comando Ex, :pwd
che è la mia directory home da /home/username
quando ho avviato la sessione vim da essa.
Perché funziona quando chiedo di cercare nella directory di lavoro corrente mentre non funziona quando chiedo di cercare in una cartella arbitraria come /etc
?
Ora, se cambio la mia directory di lavoro da /home/username
a /etc
con il comando vim Ex :cd /etc
e riprovo lo stesso comando di prima, di nuovo si sbaglia:
:next `find . -name '*.conf'`
E79: Cannot expand wildcards
Perché lo stesso comando funziona quando sono nella mia cartella home ma non quando ci sono /etc
?
Sono sicuro che c'è della logica, ma non riesco a trovarne uno.
Qual è la sintassi generale e corretta per popolare l'arglist con un comando shell arbitrario (contenente una stella, una pipe, cercando in qualsiasi directory da qualsiasi directory di lavoro)?
Sto usando vim versione 7.4.942 e zsh è la mia shell predefinita. Ho testato questi comandi con un minimo di inizializzazioni ( vim -u NORC -N
) da bash e da zsh.
Devo configurare vim per chiamare bash e non 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
, vedi: vi.stackexchange.com/a/5618/4939 ) ma sono curioso di sapere come fallo direttamente dalla sessione corrente. Se non è possibile, va bene, ma dopo aver letto l'aiuto sembra che possa essere fatto. Se lo è, vorrei capire perché vim reagisce in modo così diverso a comandi simili.
find /etc -name '*.conf'
non funzionasse, penso che alcuni nomi divertenti escano da quel comando e, questo potrebbe essere il motivo per cui ha funzionato quando è stato inviato grep
.
vim $(find . -name ver*.c)