Arglist'i doldurmak için backtick-expand nasıl kullanılır?


11

Yardımdan :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.

Yardımdan alınan komutu yazarsam bir hata alırım:

:next `find . -name ver\\*.c -print
E79: Cannot expand wildcards  

Yardımdaki örnek neden bir yerine iki ters eğik çizgi kullanıyor ve neden çalışmıyor?

Aşağıdaki çalışma:

  • Yıldızı findprogramdan önce kabuk tarafından genişletilmekten koruyan iki ters eğik çizgiden birini kaldırırsam :

    :next `find . -name ver\*.c -print`
    
  • Her iki ters eğik çizgiyi kaldırır ve desenin etrafına tek tırnak koyarsam ver*.c:

    :next `find . -name 'ver*.c' -print`
    

Bu noktaya kadar, kural şu ​​şekildedir:
kabuk komutunuz bir yıldız içeriyorsa ve kabuğun komuttan önce genişlemesini istemiyorsanız, önüne bir ters eğik çizgi koyun veya desenin etrafına tek tırnak koyun .

Ancak yardım başka bir örnek veriyor:

:view `ls -t *.patch  \| head -n1`

Bu komut herhangi bir değişiklik yapılmadan çalışır, tek tırnak işareti gerekmez, ters eğik çizgi gerekmez.
Çalışmasının nedeni, lskomutun (komutun -nameargümanının aksine find) birden çok dosya bağımsız değişkenini kabul etmesinin ve kabuk genişlemesinde sorun görmemesinin nedeni olduğunu varsayalım *.patch.

Şimdi, hadi ben uzantılı tüm dosyalar için bakmak istiyorum demek .confiçeride /etcbir klasöre ve boru çıkışı findiçin grepdizeyi içeren tek eşleşmeleri almak için input.
Kabukta, herhangi bir çalışma dizininden şunu yazardım:

find /etc -name '*.conf' | grep input

Ve işe yarayacaktı.

Vim'de, aynı komutu etrafına ters tırnaklar koyarak ve vim'in komut sonlandırması olarak yorumlamasını önlemek için boru sembolünün önüne bir ters eğik çizgi yazacağım:

:next `find /etc -name '*.conf' \| grep input`

Ve çalışıyor.

Şimdi, aynı komutu dikey olmadan yazarsam ve grep inputbir hata alırım:

:next `find /etc -name '*.conf'`
E79: Cannot expand wildcards

Yıldızı tek tırnak işareti ile korumama rağmen bu durumda neden bir hata var?
Ve şimdi neden bir hata var, ama daha önce boru ve ile değil grep input?

Anlamaya çalışmak için daha basit bir komut buldum:

find . -name '*.conf'

.confÇalışma dizininde uzantıya sahip tüm dosyaları arar . Komut kabukta çalışır.

Vim'de test etmek için şunu yazdım: :next `find . -name '*.conf'`
Ve işe yarıyor. Bu durumda nokta , vim oturumunu başlattığımdan beri :pwdana /home/usernamedizinim olan Ex komutu tarafından görüntülenen geçerli çalışma dizinimi temsil eder.

Geçerli çalışma dizininde arama yapmak istediğimde neden çalışıyor, ancak gibi rasgele bir klasörde arama yapmak istediğimde çalışmıyor /etc?

Şimdi, benim çalışma dizinini değiştirirsem /home/usernameiçin /etcvim Ex komutuyla :cd /etcve yine daha önce olduğu gibi hatalar aynı komutu dışarı yeniden deneyin:

:next `find . -name '*.conf'`
E79: Cannot expand wildcards

Aynı komut ana klasörümdeyken neden çalışıyor ama içerideyken çalışmıyor /etc?

Eminim biraz mantık vardır, ama bir tane bulamıyorum.

Arglist'i rastgele bir kabuk komutuyla (bir yıldız, bir boru, herhangi bir çalışma dizinindeki herhangi bir dizinde arama) içeren genel ve doğru sözdizimi nedir?

Vim 7.4.942 sürümünü kullanıyorum ve zsh benim varsayılan kabuğum . Bu komutları vim -u NORC -Nbash'tan ve zsh'den en az başlatma ( ) ile test ettim .

Vim'yi bassh'ı çağırmak için zsh yerine yapılandırmam gerekir mi?


Ben vim bağımsız değişken olarak geçirilen tüm dosyaları ile başlatmak için çalıştı olup olmadığını merak ediyorum? Şunu demek istiyorum:vim $(find . -name ver*.c)
Vlad GURDIGA

@VladGURDIGA Sadece denedim ve onlar kabuğundan beklendiği gibi bütün iş: 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')
Saginaw

@VladGURDIGA Ama argüman listesini geçerli oturumdan çıkmadan nasıl dolduracağımı bilmek istiyorum, çünkü genellikle sadece bir tane var. Kabukta dolaşabilir--remote , bir grup dosyayı arayabilir ve bir Vim sunucusuna gönderebilirim (argümanla , bkz: vi.stackexchange.com/a/5618/4939 ) ama nasıl yapılacağını merak ediyorum doğrudan geçerli oturumdan yapın. Mümkün değilse bu iyi, ama yardımı okuduktan sonra yapılabilir gibi görünüyor. Eğer öyleyse, vim'in neden benzer komutlara bu kadar farklı tepki verdiğini anlamak istiyorum.
saginaw

Hey, ilk örnek komutta kapanış backtick'i kaçırdığınız anlaşılıyor. ;) Bununla birlikte, yardımın örneğini, burada açıklandığı gibi, kabuk genişlemesini önlemek için biri yerine iki ters eğik çizgi kullanın: unix.stackexchange.com/q/104260/23669 .
Vlad GURDIGA

Çalışmama durumunda, find /etc -name '*.conf'o komuttan bazı komik isimler geldiğini düşünürdüm, ve bu yüzden tıkandığında çalışmasının nedeni olabilir grep.
Vlad GURDIGA

Yanıtlar:


6

Arglist'i rastgele bir kabuk komutuyla doldurmak için backtick-expand nasıl kullanılacağını hala bilmiyorum, ancak bir çözüm buldum.

Gönderen :help `=:

You can have the backticks expanded as a Vim expression, instead of as an
external command, by putting an equal sign right after the first backtick,
e.g.:
    :e `=tempname()`
The expression can contain just about anything, thus this can also be used to
avoid the special meaning of '"', '|', '%' and '#'.  However, 'wildignore'
does apply like to other wildcards.

Yani, doğrudan böyle bir kabuk komutunu genişletmek yerine:

:args `shell command`

Shell komutunu Vim işlevine gönderebilir ve sonuç ifadesini şu şekilde genişletmek için systemlist()ifade yazmacını kullanabiliriz =:

:args `=systemlist("shell command")`

Bazı tuş vuruşlarını kaydetmek için, vimrc'de ( :PAPopulate Arglist için) aşağıdaki Ex komutunu tanımladım :

command! -nargs=1 PA args `=systemlist(<q-args>)`

Ve çeşitli kabuk komutlarıyla test etti:

:PA find . -name ver\*.c -print 2>/dev/null
:PA find . -name 'ver*.c' -print 2>/dev/null
:PA ls -t *.patch  | head -n1
:PA find /etc -name '*.conf' 2>/dev/null | grep input
:PA find /etc -name '*.conf' 2>/dev/null
:PA find . -name '*.conf' 2>/dev/null

Şimdiye kadar beklendiği gibi çalışıyor ve komut kabukta olduğu gibi yazılabilir (örneğin borudan kaçmaya gerek yok).
Doğrudan backtick genişlemesinden daha tutarlı ve güvenilir görünüyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.