จากความช่วยเหลือ: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 ตีความว่าเป็นการยกเลิกคำสั่ง:
: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'`
และใช้งานได้ ในกรณีนี้ dot ย่อมาจากไดเร็กทอรีการทำงานปัจจุบันของฉันตามที่แสดงโดยคำสั่ง Ex :pwd
ซึ่งเป็นโฮมไดเร็กทอรีของ/home/username
ฉันตั้งแต่ฉันเรียกใช้เซสชัน vim จากมัน
ทำไมมันทำงานเมื่อฉันขอให้ค้นหาในไดเรกทอรีการทำงานปัจจุบันในขณะที่มันไม่ทำงานเมื่อฉันขอให้ค้นหาในโฟลเดอร์โดยพลการเช่น/etc
?
ตอนนี้ถ้าฉันเปลี่ยนไดเร็กตอรี่การทำงานของฉันจาก/home/username
เป็น/etc
ด้วยคำสั่ง vim Ex :cd /etc
และลองคำสั่งเดิมเหมือนเดิมอีกครั้งมันจะผิดพลาดอีกครั้ง:
:next `find . -name '*.conf'`
E79: Cannot expand wildcards
ทำไมการทำงานคำสั่งเดียวกันเมื่อผมอยู่ในโฟลเดอร์ที่บ้านของฉัน แต่ไม่เมื่อผมอยู่ใน/etc
?
ฉันแน่ใจว่ามีเหตุผลบางอย่าง แต่ฉันไม่สามารถหาได้
อะไรคือไวยากรณ์ทั่วไปและที่ถูกต้องในการเติมข้อมูล arglist ด้วยคำสั่งเชลล์โดยพลการ (ประกอบด้วยดาว, ไพพ์, ค้นหาในไดเรกทอรีใด ๆ
ฉันใช้ vim รุ่น7.4.942และ zsh เป็นเชลล์เริ่มต้นของฉัน ฉันทดสอบคำสั่งเหล่านี้ด้วยการกำหนดค่าเริ่มต้นขั้นต่ำ ( vim -u NORC -N
) จาก bash และ zsh
ฉันจำเป็นต้องกำหนดค่ากลุ่มให้เรียก bash ไม่ใช่ 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
ดู: vi.stackexchange.com/a/5618/4939 ) แต่ฉันอยากรู้วิธีการ ทำโดยตรงจากเซสชั่นปัจจุบัน ถ้ามันเป็นไปไม่ได้มันก็ใช้ได้ แต่หลังจากอ่านความช่วยเหลือแล้วดูเหมือนว่ามันสามารถทำได้ ถ้าเป็นเช่นนั้นฉันอยากจะเข้าใจว่าทำไมกลุ่มเสียงตอบสนองจึงต่างกับคำสั่งที่คล้ายกัน
find /etc -name '*.conf'
grep
vim $(find . -name ver*.c)