เป็นไปได้หรือไม่ที่จะสั่งคำสั่ง vim เป็นกลุ่ม?


18

ฉันต้องการเรียกใช้เชลล์ต่อไปนี้

wea-this is the end of the second word | vim j
exit 0

ซึ่งฉันหวังว่าจะไปป์จังหวะสำคัญw(เลื่อนไปข้างหน้าคำ) จากนั้นe(จบคำ) จากนั้นa(ต่อท้าย) แล้ว-this is the end of the second word( ต่อท้าย) (ข้อความ) ไปยังเอกสาร Vim jที่มีคำซึ่งมีคำอยู่แล้ว

ข้อผิดพลาดต่อไปนี้เกิดขึ้นเมื่อฉันรันเชลล์สคริปต์

/root/bin/tt.sh: line 1: wea-this: command not found
Vim: Warning: Input is not from a terminal

ฉันใช้ Ubuntu 14.04 คำตอบสองประเภทจะได้รับการชื่นชม:

  1. วิธีใช้ piping เพื่อให้ได้ผลลัพธ์ตามที่ต้องการ
  2. อีกวิธีที่ฉันสามารถใช้ "คำสั่ง Vim" (ไม่ใช่คำสั่ง ed หรือ sed) เพื่อแก้ไขเอกสารข้อความจากเชลล์สคริปต์

1
|ท่อตัวอักษรผลลัพธ์ของคำสั่งหนึ่งไปยังอีก wea-thisไม่ใช่คำสั่ง ไม่สามารถใช้การวางท่อเพื่อให้ได้สิ่งที่คุณต้องการ มันจะทำให้ stdin ของ Vim เป็นแอปพลิเคชันมือซ้ายไม่ใช่แป้นพิมพ์ หากคุณต้องการให้ stdin เป็นบัฟเฟอร์ในกลุ่มให้เริ่มด้วยเครื่องหมายลบสำหรับชื่อไฟล์: echo Hello, world! | vim -.
dash-tom-bang

คำตอบ:


15

ในการแทรกสตริง"hello"บนบรรทัดแรกของไฟล์jคุณสามารถพิมพ์คำสั่งต่อไปนี้ในเชลล์ของคุณ:

vim +"1 | put! ='hello'" j

  • :1 ย้ายเคอร์เซอร์ไปที่บรรทัดแรกของบัฟเฟอร์
  • :put! ='hello' วางสตริง "hello" เหนือบรรทัดปัจจุบัน

ในการแทรกสตริง"hello"จากนั้นให้บันทึกและออกจากไฟล์:

vim +"1 | put! ='hello' | x" j

เหมือนกับเมื่อก่อนเราเพิ่งเพิ่มคำสั่ง Ex :xที่จะบันทึกและออก

โดยทั่วไปคุณสามารถเรียกใช้คำสั่ง Ex ใด ๆ ในไฟล์จากเชลล์แบบโต้ตอบหรือจากสคริปต์ทุบตีแบบนี้:

vim +'Ex command1 | Ex command2 | ...' file

หากคุณมีคำสั่ง Ex จำนวนมากคุณสามารถเขียนคำสั่งเหล่านั้นทั้งหมดในไฟล์เฉพาะ (เรียกว่าตัวอย่างmyExCommands.vim) หนึ่งคำสั่งต่อบรรทัดจากนั้นจากเชลล์หรือสคริปต์ที่คุณสามารถหาได้ (ด้วยคำสั่ง Ex :sourceหรือรุ่นย่อ:so) แบบนี้:

vim +'so myExCommands.vim' file

แก้ไข

ฉันเห็นคุณแก้ไขคำถามของคุณแล้ว
ผมคิดว่าคำตอบก่อนหน้านี้ยังคงใช้เพราะคุณสามารถรันคำสั่งปกติใด ๆ จากโหมด Ex กับคำสั่งที่ได้รับสิทธิและ:normal:execute

ตัวอย่างเช่นสมมติว่าคุณต้องการ:

  • เลื่อนเคอร์เซอร์ไปที่บรรทัดแรกของบัฟเฟอร์ ( 1G)
  • เลื่อนเคอร์เซอร์ไปที่อักขระที่ไม่ใช่ช่องว่างตัวแรกบนบรรทัด ( _)
  • เลื่อนเคอร์เซอร์ไปข้างหน้าหนึ่งคำ ( w)
  • เลื่อนเคอร์เซอร์ไปที่ท้ายคำใหม่ ( e)
  • เข้าสู่โหมดแทรกหลังจากตัวละครใต้เคอร์เซอร์ ( a)
  • แทรกสตริง hello
  • บันทึกและออก ( :x)

หากต้องการทำสิ่งนี้กับไฟล์jให้พิมพ์จาก shell:

vim +"execute 'normal! 1G_weahello' | x" j

สำหรับข้อมูลเพิ่มเติมดู:

:help +cmd
:help :normal
:help :execute

ฉันไม่สามารถอธิบายเป้าหมายได้อย่างเต็มที่ ฉันต้องการใช้คำสั่ง vims เช่น w เพื่อเลื่อนไปข้างหน้าคำและเช่นนั้น ฉันจะแก้ไขคำถามของฉันเพื่อแก้ไข
Jason Basanese

@JasonBasanese ฉันได้แก้ไขคำตอบของฉันทำคำสั่ง Ex :normalแล้ว:executeทำสิ่งที่คุณต้องการ?
saginaw

9

นี่คือวิธีที่คุณสามารถใช้คำสั่งโหมดปกติแทนที่จะเป็นเพียงคำสั่ง ex เพื่อแก้ไขสตรีมที่นำเสนอไปยัง Vim จาก stdin นี่ไม่ใช่ตัวอย่างที่มีประโยชน์มาก แต่มันแสดงให้เห็นถึงเทคนิคต่าง ๆ ที่เกี่ยวข้อง สมมติว่าเปลือกของคุณทุบตี

echo "The brown fox jumped." | vim -s <(printf 'wcwred\e:wq! foo\n') -

-ในตอนท้ายบอกเป็นกลุ่มที่จะอ่านข้อความ (ไม่ใช่คำสั่ง) จาก stdin -sบอกเป็นกลุ่มที่จะดำเนินการกดแป้นพิมพ์จากไฟล์ที่ระบุ ในกรณีนี้ไฟล์เป็นผลลัพธ์ของการทดแทนกระบวนการทุบตี <(...)จะถูกแทนที่ด้วยชื่อของไปป์ที่มีชื่อ เอาต์พุตของไพพ์เป็นเอาต์พุตของคำสั่งภายในวงเล็บ ย้ายเคอร์เซอร์โดยหนึ่งในคำพูดและการเปลี่ยนแปลงที่คำถัดไปwcwred\e บันทึกผลไปยังแฟ้มแม้ว่าไฟล์ที่มีอยู่แล้ว ผลลัพธ์ที่ได้คือไฟล์ที่มีข้อความred:wq! foo\nfoofooThe red fox jumped.

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อเหล่านี้ให้ดู

:help -file
:help -s

ดูProcess Substitutionส่วนของbash(1)หน้าคน


เพิ่มไปยัง ~ / .zshrc: ของvimx () { vi -s <(echo "$1"':wq') "$2" &> /dev/null; }ฉัน vimx 'iThe brow fox jumped.\e' foo; vimx 'wcwred\efjdwiclimbed\e' foo; cat fooตอนนี้ฉันสามารถ เรียบร้อย!
Leonard Pauli

4

ฉันได้ค้นพบวิธีการที่เอาท์พุทของโปรแกรมเมื่อเปลี่ยนเส้นทางจาก sub-shell เป็นเรื่องง่ายมาก:

vim <( program )

ตัวอย่าง:

 vim <( grep -nH  hello  myFile.cpp )
 vim <( find . -name '*.cpp' -exec grep -nH code_expr {} \+ )

4

ฉันมีความต้องการเช่นเดียวกับคุณ: ฉันต้องการเขียนคำสั่ง vim ปกติและมีการแก้ไขสตรีมไปป์ไลน์ ฉันรู้สึกผิดหวังกับความยากลำบากในการใช้เสียงเรียกเข้าแบบปกติในลักษณะนี้ (มีธงจำนวนมาก!) ตามที่ระบุไว้ในตัวเลือกเสียงเรียกเข้าเริ่มต้น

ดังนั้นผมเขียนกระดาษห่อเล็ก ๆ ในกลุ่มที่จะทำมัน: https://github.com/MilesCranmer/vim-stream/ vimsมันเรียกว่า

หัวใจของเสื้อคลุมเป็นคำสั่งต่อไปนี้:

vim - -nes "${vim_cmds[@]}" -c ':q!' | tail -n +2

การใช้สิ่งนี้กับการสร้างคำสั่งที่ฉันทำมันออกมาได้ค่อนข้างกระชับและเนื่องจาก vim เป็นตัวแก้ไขvimsโมดอล มีสามโหมดหลักที่มีประโยชน์สำหรับการใช้ความคิดในการแก้ไขไปป์ไลน์:

[-t|--turn-off-mode] - (Default mode)
                       Every string is a vim command line, e.g., '%g/foo/d' deletes
                       all lines with foo.
[-e|--exe-mode] -      Translated to '%g/$1/exe "norm $2"', see examples below
[-s|--simple-mode] -   Like exe-mode, but runs on 1st line only

ดูนี้:

$ echo "Hello World" | vims -s "ea Beautiful"
Hello Beautiful World

ดังนั้นeไปที่จุดสิ้นสุดHelloแล้วaเริ่มต่อท้าย

มีบางสิ่งที่นักเล่นในโหมด exe เพื่อคอมเม้นท์บรรทัดที่มีmy_bad_varและลบบรรทัดก่อนหน้า

cat my_script.cpp | vims -e 'my_bad_var' 'I//\<esc>kdd'

ซึ่งแปลเป็นvims '%g/my_bad_var/exe "norm I//\<esc>kdd"'- Iเป็นคำสั่งให้เริ่มแทรกที่จุดเริ่มต้นของบรรทัดและ//ลำดับความคิดเห็น \<esc>kddดันแป้น Escape เลื่อนขึ้นบรรทัดหนึ่งแล้วลบบรรทัด

ฉันมีตัวอย่างทั้งหมด 11 รายการใน repo ฉันขอแนะนำให้คุณลองดู นี่เป็นอีกวิธีที่ทำให้ vim เป็นเหมือน sed สำหรับการป้อนข้อมูลสตรีม (แต่ยังคงรักษาแมโคร vim ที่คุณรักเอาไว้!)


3

นี่เป็นคำถามที่ค่อนข้างเก่า แต่ฉันรู้สึกว่ามันคุ้มค่าที่จะสนับสนุนว่าหาก distro / OS ของคุณมีสิทธิ์เข้าถึงmoreutilsคุณสามารถติดตั้งได้และใช้vipeเป็นส่วนเสริมมาตรฐานเพื่อvim:

echo foo | vipe # Now you can edit "foo" to be "bar"!

moreutilsมีประโยชน์อย่างยิ่งสำหรับเครื่องมืออื่น ๆ เช่นกันและฉันขอแนะนำอย่างยิ่งหากคุณเป็นผู้ใช้บรรทัดคำสั่งที่จริงจัง! :) ดูที่การแนะนำของผู้เขียน (ลิงค์ก่อนหน้า) เพื่อดูรายละเอียดเพิ่มเติม

moreutilsควรจะสามารถใช้ได้โดยทั่วไปให้มากที่สุด * ระวังเหมือน distros ผ่านผู้จัดการแพคเกจและผ่าน Homebrew บน Mac ตัวอย่างเช่น...

# Arch Linux and MSYS2 (more below) as part of the `community` repo
pacman -Sy moreutils


# Mac OS and Homebrew
brew install moreutils

moreutilsยังเป็นส่วนหนึ่งของที่เก็บแพคเกจ MSYS2ดังนั้นคุณจึงสามารถใช้ในทางเทคนิคบน Windows ได้เช่นกัน :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.