Dari bantuan :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.
Jika saya mengetik perintah yang diambil dari bantuan, saya mendapatkan kesalahan:
:next `find . -name ver\\*.c -print
E79: Cannot expand wildcards
Mengapa contoh dari bantuan menggunakan dua garis miring terbalik bukan satu, dan mengapa tidak berhasil?
Pekerjaan berikut:
Jika saya menghapus salah satu dari dua garis miring terbalik yang melindungi bintang agar tidak diperluas oleh shell sebelum
find
program::next `find . -name ver\*.c -print`
Jika saya menghapus kedua garis miring terbalik dan menempatkan tanda kutip tunggal di sekitar pola
ver*.c
::next `find . -name 'ver*.c' -print`
Hingga saat ini, aturannya adalah:
jika perintah shell Anda berisi bintang dan Anda tidak ingin shell memperluasnya sebelum perintah, letakkan satu garis miring terbalik di depannya atau letakkan tanda kutip tunggal di sekitar pola .
Tetapi bantuan itu memberi contoh lain:
:view `ls -t *.patch \| head -n1`
Perintah ini berfungsi tanpa modifikasi, tidak perlu tanda kutip tunggal, tidak perlu backslash.
Saya kira alasan mengapa ia bekerja adalah karena ls
perintah (bertentangan dengan -name
argumen dari find
perintah) menerima beberapa argumen file dan tidak melihat masalah dengan shell yang mengembang *.patch
.
Sekarang, katakanlah saya ingin mencari semua file dengan ekstensi .conf
di dalam /etc
folder dan pipa output dari find
untuk grep
mendapatkan hanya pertandingan yang mengandung string input
.
Dalam shell, dari direktori kerja mana pun, saya akan mengetik:
find /etc -name '*.conf' | grep input
Dan itu akan berhasil.
Dalam vim, saya akan mengetik perintah yang sama dengan menempatkan backtick di sekitarnya, dan backslash di depan simbol pipa untuk mencegah vim menafsirkannya sebagai terminasi perintah:
:next `find /etc -name '*.conf' \| grep input`
Dan itu berhasil.
Sekarang, jika saya mengetik perintah yang sama tanpa pipa dan grep input
, saya mendapatkan kesalahan:
:next `find /etc -name '*.conf'`
E79: Cannot expand wildcards
Mengapa ada kesalahan dalam hal ini meskipun saya melindungi bintang dengan tanda kutip tunggal?
Dan mengapa ada kesalahan sekarang, tetapi tidak sebelum dengan pipa dan grep input
?
Untuk mencoba memahami, saya telah datang dengan perintah yang lebih sederhana:
find . -name '*.conf'
Itu mencari semua file dengan ekstensi .conf
di direktori kerja. Perintah itu bekerja di shell.
Untuk mengujinya di vim, saya mengetik: :next `find . -name '*.conf'`
Dan itu berhasil. Dalam hal ini titik adalah singkatan dari direktori kerja saya saat ini seperti yang ditampilkan oleh perintah Ex :pwd
yang merupakan direktori home saya /home/username
sejak saya meluncurkan sesi vim darinya.
Mengapa itu berfungsi ketika saya meminta untuk mencari di direktori kerja saat ini sedangkan itu tidak berfungsi ketika saya meminta untuk mencari di folder yang sewenang-wenang seperti /etc
?
Sekarang, jika saya mengubah direktori kerja saya dari /home/username
ke /etc
dengan perintah vim Ex :cd /etc
dan coba lagi perintah yang sama seperti sebelumnya, sekali lagi kesalahan keluar:
:next `find . -name '*.conf'`
E79: Cannot expand wildcards
Mengapa perintah yang sama berfungsi ketika saya berada di folder rumah saya tetapi tidak ketika saya berada di /etc
?
Saya yakin ada beberapa logika, tetapi saya tidak dapat menemukannya.
Apa sintaksis umum dan yang benar untuk mengisi arglist dengan perintah shell arbitrary (berisi bintang, pipa, mencari di direktori mana saja dari direktori kerja)?
Saya menggunakan vim versi 7.4.942 dan zsh adalah shell default saya. Saya menguji perintah ini dengan inisialisasi minimum ( vim -u NORC -N
) dari bash dan juga dari zsh.
Apakah saya perlu mengkonfigurasi vim untuk memanggil bash dan bukan zsh?
sumber
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
, lihat: vi.stackexchange.com/a/5618/4939 ) tapi saya ingin tahu bagaimana caranya lakukan langsung dari sesi saat ini. Jika tidak mungkin itu baik-baik saja, tetapi setelah membaca bantuan itu tampaknya bisa dilakukan. Jika ya, saya ingin memahami mengapa vim bereaksi sangat berbeda terhadap perintah serupa.find /etc -name '*.conf'
tidak bekerja, saya pikir beberapa nama lucu keluar dari perintah itu, dan, ini mungkin menjadi alasan mengapa itu berhasil ketika disalurkangrep
.Jawaban:
Saya masih tidak tahu bagaimana menggunakan backtick-expansion untuk mengisi argumen dengan perintah shell arbitrer, namun saya telah menemukan solusinya.
Dari
:help `=
:Jadi, alih-alih memperluas secara langsung perintah shell seperti ini:
Kami dapat mengirim perintah shell ke fungsi Vim
systemlist()
dan menggunakan register ekspresi=
untuk memperluas ekspresi yang dihasilkan seperti ini:Untuk menyimpan beberapa penekanan tombol, saya telah mendefinisikan perintah Ex berikut di vimrc saya (
:PA
untuk Populate Arglist):Dan mengujinya dengan berbagai perintah shell:
Sejauh ini berfungsi seperti yang diharapkan dan perintah dapat diketik seperti di shell (tidak perlu keluar dari pipa misalnya).
Tampaknya lebih konsisten dan dapat diandalkan daripada ekspansi backtick langsung.
sumber