Arglist को पॉप्युलेट करने के लिए बैकटिक-विस्तार का उपयोग कैसे करें?


11

मदद से :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.

यदि मैं मदद से ली गई कमांड टाइप करता हूं, तो मुझे एक त्रुटि मिलती है:

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

मदद से उदाहरण एक के बजाय दो बैकस्लैश का उपयोग क्यों करता है, और यह काम क्यों नहीं करता है?

निम्नलिखित कार्य:

  • यदि मैं दो बैकस्लैश में से एक को हटाता हूं जो findकार्यक्रम से पहले शेल द्वारा स्टार को विस्तारित होने से बचाता है :

    :next `find . -name ver\*.c -print`
    
  • यदि मैं बैकस्लैश के दोनों को हटाता हूं और पैटर्न के चारों ओर एकल उद्धरण रखता हूं ver*.c:

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

इस बिंदु तक, नियम ऐसा प्रतीत होता है:
यदि आपके शेल कमांड में एक स्टार है और आप नहीं चाहते हैं कि शेल कमांड से पहले इसे विस्तारित करे, तो इसके सामने एक बैकस्लैश डालें या पैटर्न के चारों ओर सिंगल कोट्स डालें

लेकिन मदद एक और उदाहरण देती है:

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

यह कमांड बिना किसी संशोधन के काम करता है, सिंगल कोट्स की जरूरत नहीं, बैकस्लैश की जरूरत नहीं।
मुझे लगता है कि इसका कारण यह है कि यह काम करता है क्योंकि lsकमांड (कमांड के -nameतर्क के विपरीत find) कई फ़ाइल तर्क स्वीकार करता है और शेल के विस्तार में कोई समस्या नहीं देखता है *.patch

अब, मान लें कि मैं फ़ोल्डर के .confअंदर विस्तार के साथ सभी फाइलों को देखना चाहता हूं /etcऔर केवल स्ट्रिंग से मिलान findकरने के grepलिए आउटपुट को पाइप करता हूं input
शेल में, किसी भी कार्यशील निर्देशिका से, मैं टाइप करूंगा:

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

और यह काम करेगा।

Vim में, मैं उसी कमांड को उसके चारों ओर बैकटिक्स लगाऊंगा, और पाइप सिंबल के सामने बैकस्लैश को vim को कमांड टर्मिनेशन के रूप में व्याख्या करने से रोकने के लिए:

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

और यह काम करता है।

अब, यदि मैं पाइप और के बिना एक ही कमांड टाइप करता हूं, तो मुझे grep inputएक त्रुटि मिलती है:

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

इस मामले में एक त्रुटि क्यों है, हालांकि मैंने सिंगल कोट्स के साथ स्टार की रक्षा की है?
और अब एक त्रुटि क्यों है, लेकिन पाइप और के साथ पहले नहीं grep input?

समझने की कोशिश करने के लिए, मैं एक सरल आदेश के साथ आया हूं:

find . -name '*.conf'

यह .confकार्यशील निर्देशिका में विस्तार के साथ सभी फाइलों को देखता है । कमांड शेल में काम करता है।

इसे जांचने के लिए, मैंने टाइप किया: :next `find . -name '*.conf'`
और यह काम करता है। इस मामले में डॉट मेरी वर्तमान कार्यशील निर्देशिका के लिए है जैसा कि पूर्व कमांड द्वारा प्रदर्शित किया गया है :pwdजो कि मेरे घर की निर्देशिका है /home/usernameक्योंकि मैंने इससे विम सत्र शुरू किया था।

जब मैं वर्तमान कार्यशील निर्देशिका में खोज करने के लिए कहता हूं तो यह काम क्यों करता है, जब मैं मनमाने फ़ोल्डर में खोज करने के लिए कहता हूं तो यह काम नहीं करता है /etc?

अब, अगर मैंने अपने कार्यशील निर्देशिका को बदलने /home/usernameके लिए /etcvim पूर्व आदेश के साथ :cd /etcऔर एक ही आदेश से पहले के रूप में, यह त्रुटियों पुन: प्रयास फिर से:

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

जब मैं अपने होम फोल्डर में होता हूं तो वही कमांड क्यों काम करता है लेकिन जब मैं अंदर होता हूं तो नहीं /etc?

मुझे यकीन है कि कुछ तर्क हैं, लेकिन मुझे एक नहीं मिल रहा है।

मनमाने ढंग से शेल कमांड (किसी स्टार, पाइप, किसी भी कार्यशील निर्देशिका से किसी भी निर्देशिका में खोज करना) के साथ arglist को आबाद करने के लिए सामान्य और सही सिंटैक्स क्या है?

मैं विम संस्करण का उपयोग कर रहा हूँ 7.4.942 और zsh मेरा डिफ़ॉल्ट शेल है। मैंने इन कमांड्स को न्यूनतम इनिशियलाइज़ेशन ( vim -u NORC -N) से बैश के साथ-साथ zsh से टेस्ट किया।

क्या मुझे बैश को कॉल करने के लिए विम को कॉन्फ़िगर करने की आवश्यकता है न कि zsh?


अगर आप उन सभी फाइलों के साथ बहस शुरू करने की कोशिश कर रहे हैं, तो मुझे आश्चर्य हो रहा है? मेरा मतलब कुछ इस तरह है:vim $(find . -name ver*.c)
व्लाद गुड़िगा

@VladGURDIGA मैं बस की कोशिश की है और वे सब काम खोल से अपेक्षा के अनुरूप: 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 लेकिन मैं जानना चाहूंगा कि वर्तमान सत्र को समाप्त किए बिना कैसे arglist को आबाद करना है क्योंकि मेरे पास आमतौर पर केवल एक है। मैं शेल में भी घूम सकता हूं, फाइलों के समूह को खोज सकता हूं और उन्हें विम सर्वर पर भेज सकता हूं (तर्क के साथ --remote, देखें: vi.stackexchange.com/a/5618/4939 ) लेकिन मैं यह जानने के लिए उत्सुक हूं कि कैसे इसे वर्तमान सत्र से सीधे करें। यदि यह संभव नहीं है तो ठीक है, लेकिन मदद पढ़ने के बाद ऐसा लगता है कि यह किया जा सकता है। यदि यह है, तो मैं यह समझना चाहूंगा कि विम समान कमांड के लिए अलग तरह से प्रतिक्रिया क्यों करता है।
सागिनॉ

अरे, ऐसा लगता है जैसे पहले सैंपल कमांड में आपको क्लोजिंग बैकटिक की याद आ रही है। ;) इसके अलावा हालांकि, मुझे लगता है कि शेल के विस्तार को रोकने के लिए एक के बजाय दो बैकस्लैश का उपयोग करने में मदद से उदाहरण मिलता है, जैसा कि यहां बताया गया है: unix.stackexchange.com/q/104260/23669
व्लाद गुड़िगा

find /etc -name '*.conf'काम नहीं करने के मामले में , मुझे लगता है कि कुछ मजेदार नाम उस कमांड से निकलते हैं, और, यही कारण हो सकता है कि जब यह पाइप के माध्यम से काम करता है grep
व्लाद गुड़िगा

जवाबों:


6

मुझे अभी भी पता नहीं है कि मनमाने ढंग से शेल कमांड के साथ arglist को पॉप्युलेट करने के लिए बैकटिक-एक्सपेंशन का उपयोग कैसे किया जाता है, हालाँकि मुझे वर्कअराउंड मिल गया है।

से :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.

इसलिए, इस तरह सीधे एक शेल कमांड का विस्तार करने के बजाय:

:args `shell command`

हम शेल कमांड को विम फंक्शन में भेज सकते systemlist()हैं और एक्सप्रेशन रजिस्टर =का इस्तेमाल इस तरह कर सकते हैं:

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

कुछ कीस्ट्रोक्स को बचाने के लिए, मैंने अपने vimrc ( :PAपॉपुलेट आर्गलिस्ट के लिए) में निम्न Ex कमांड को परिभाषित किया है :

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

और विभिन्न शेल कमांड के साथ इसका परीक्षण किया:

: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

अब तक यह उम्मीद की तरह काम करता है और कमांड टाइप किया जा सकता है क्योंकि यह शेल में होगा (उदाहरण के लिए पाइप से बचने की आवश्यकता नहीं)।
यह प्रत्यक्ष बैकटिक-विस्तार की तुलना में अधिक सुसंगत और विश्वसनीय लगता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.