เสียงเรียกเข้า: แทรกอักขระตัวเดียวกันข้ามหลายบรรทัด


306

บางครั้งฉันต้องการแก้ไขบล็อกข้อความแบบเห็นภาพข้ามหลายบรรทัด

ตัวอย่างเช่นฉันจะใช้ข้อความที่มีลักษณะเช่นนี้:

name
comment
phone
email

และทำให้มันเป็นแบบนี้

vendor_name
vendor_comment
vendor_phone
vendor_email

ปัจจุบันวิธีที่ฉันจะทำตอนนี้คือ ...

  1. เลือกทั้ง 4 แถวของบล็อกโดยการกดVจากนั้นjสี่ครั้ง
  2. >เยื้องกับ
  3. hกลับไปหนึ่งตัวอักษรด้วย
  4. Ctrlvไปเพื่อป้องกันโหมดภาพกับ
  5. เลือกสี่แถวโดยกดjสี่ครั้ง ณ จุดนี้คุณได้เลือกบล็อกที่มองเห็น 4x1 ช่องว่าง (สี่แถวและหนึ่งคอลัมน์)
  6. Cกด สังเกตุสิ่งนี้เยื้องไปทางซ้ายทีละคอลัมน์
  7. พิมพ์ a " vendor_"โดยไม่ต้องใส่เครื่องหมายคำพูด สังเกตเห็นพื้นที่พิเศษที่เราต้องใส่กลับ
  8. Escกด นี่เป็นหนึ่งในไม่กี่ครั้งที่ฉันใช้Escเพื่อออกจากโหมดแทรก Ctrlcจะแก้ไขบรรทัดแรกเท่านั้น
  9. ทำซ้ำขั้นตอนที่ 1
  10. <เยื้องไปทางอื่นด้วย

ฉันไม่จำเป็นต้องเยื้องถ้ามีช่องว่างอย่างน้อยหนึ่งคอลัมน์หน้าคำ cฉันจะไม่จำเป็นต้องมีช่องว่างถ้าผมไม่ได้มีการยกเลิกการบล็อกภาพกับ

แต่ถ้าฉันต้องชัดเจนแล้วมีวิธีทำสิ่งที่ฉันทำข้างต้นโดยไม่ต้องสร้างช่องว่างที่จำเป็นด้วยการเยื้องหรือไม่

ทำไมการแก้ไขหลายบรรทัดในครั้งเดียวจึงทำได้โดยออกจากโหมดแทรกด้วยEscมากกว่าCtrlc?


นี่คือตัวอย่างที่ซับซ้อนมากขึ้น:

name    = models.CharField( max_length = 135 )
comment = models.TextField( blank = True )
phone   = models.CharField( max_length = 135, blank = True )
email   = models.EmailField( blank = True )

ถึง

name    = models.whatever.CharField( max_length = 135 )
comment = models.whatever.TextField( blank = True )
phone   = models.whatever.CharField( max_length = 135, blank = True )
email   = models.whatever.EmailField( blank = True )

ในตัวอย่างนี้ผมจะดำเนินการบล็อกภาพแนวตั้งมากกว่าแล้วใส่กลับเข้าไปใหม่มันกลับมาระหว่างโหมดการแทรกเช่นประเภท. .whatever.หวังว่าตอนนี้คุณสามารถดูข้อเสียของวิธีนี้ ฉันกำลัง จำกัด เพียงการเลือกคอลัมน์ของข้อความที่มีทั้งหมดเหมือนกันในแนวตั้ง


9
วิธีที่ดีกว่า: ":% s / ^ / ผู้ขาย _ /"
Paul Tomblin

1
ขอบคุณสำหรับคำตอบ ใช้งานได้หากฉันต้องการเพิ่มคำต่อท้ายทุกบรรทัด แต่วิธีที่ฉันใช้สามารถทำได้ทุกตำแหน่ง ให้ฉันเพิ่มอีกตัวอย่างของฉันด้วยตัวอย่างที่ซับซ้อนมากขึ้น
hobbes3

3
จากนั้นไฮไลต์บรรทัดที่คุณต้องการเปลี่ยนด้วย shift-V และพิมพ์คำสั่งค้นหาและแทนที่ที่เหมาะสม - ในตัวอย่างที่สอง:s/models\./\0whatever./
Paul Tomblin

หลายวิธีในการบรรลุเป้าหมายข้างต้น ในการตอบคำถามทุกส่วนอย่างเต็มที่ส่วนที่ 1) ไม่ว่าจะเป็นโหมด regex หรือโหมด visual ฉันแก้ไข esc ทำงานได้ดีตามที่เสนอในคำตอบ (ฉันชอบการเลือกภาพใน GVIM) สำหรับตอนที่ 2) มาโครอาจจะง่ายที่สุดตามที่ Brian Neal นำเสนอ ทรัพยากรที่ดีที่สุดที่ฉันรู้สำหรับ "วิธีการ" ทุกประเภทเหล่านี้คือ Vim ที่ใช้งานได้โดย Drew Neil การอ่านอย่างรวดเร็วและการอ้างอิงน้ำหนักที่ยอดเยี่ยมทุกครั้งที่คุณลืมสูตร หวังว่าคำแนะนำนี้จะช่วยใครซักคนมันจะคุ้มค่ากับความพยายามสำหรับผู้ใช้ที่เป็นกลุ่มจำนวนมาก
arcseldon

@ Paul: และถ้าคุณกดแป้นพิมพ์นับคุณสามารถแทนที่ด้วย\0 &
icktoofay

คำตอบ:


912
  1. เลื่อนเคอร์เซอร์ไปในnname
  2. เข้าสู่โหมดบล็อกภาพ ( Ctrlv)
  3. กดjสามครั้ง (หรือ3j)
  4. กดI(ตัวใหญ่ i)
  5. vendor_พิมพ์ หมายเหตุ: มันจะอัปเดตหน้าจอในบรรทัดแรกเท่านั้น - จนกว่าEscจะกด (6. ) ซึ่งจะมีการอัปเดตทุกบรรทัด
  6. Escกด

mini-screencast สาธิตวิธีการ

Iต้องใช้ตัวพิมพ์ใหญ่แทนตัวพิมพ์เล็กiเนื่องจากตัวพิมพ์เล็กiตีความว่าเป็นจุดเริ่มต้นของวัตถุข้อความซึ่งค่อนข้างมีประโยชน์ในตัวมันเองเช่นสำหรับการเลือกภายในแท็กบล็อค ( it):

mini-screencast แสดงประโยชน์ของวัตถุข้อความ 'it'


12
ฉันไม่สามารถใช้สิ่งนี้ใน Windows (เนื่องจากมีการจับคู่ CTRL + V เพื่อวางคลิปบอร์ด) แต่เป็นกลุ่มได้แมปนี้กับCtrl + Qสำหรับรุ่น Windows
Arnestig

2
@Ven: กลุ่มที่ไม่ยุ่งจริง ๆ ในช่วงเวลานั้น - มันแค่รอให้คุณกดปุ่มอื่นและในที่สุดก็หมดเวลา สองการทดลองสำหรับคุณ: ครั้งแรกที่ลองกดหลบหนีและจากนั้นทันทีกดปุ่มอื่นเช่นหรือj ^Lคุณควรจะเห็นว่ากลุ่มนั้นไม่ยุ่งเลย มันแค่รอ ขั้นที่สองลองเปลี่ยน'timeout'เป็นค่าที่ต่ำกว่าเช่น80(แทนที่จะเป็นค่าเริ่มต้น1000) และสังเกตว่าหมดเวลาเร็วกว่า
icktoofay

1
@icktoofay ดูเหมือนว่าตัวแปรที่คุณหมายถึงชุดจะไม่ได้timeoutlen timeout
jez

4
@ANjaNA: หากตำแหน่งที่คุณต้องการแทรกมีทั้งหมดในคอลัมน์เดียวกัน (เช่นหากตัวเลขมีความยาวเท่ากันทั้งหมด) คุณสามารถใช้เทคนิคเดียวกันยกเว้นการกดAมากกว่าIซึ่งจะแทรกหลังจากบล็อกที่เลือกมากกว่าเดิม ถ้าเส้นของคุณมีความยาวต่างกันแสดงว่าไม่สามารถใช้งานได้ :s/$/inserted/ผมชอบที่จะใช้ทดแทนการจับคู่ท้ายของแต่ละสายนั้นเช่นการเลือกเส้นบางและการใช้
icktoofay

3
ฉันต้องกดลูกศรลงหลังจากกด esc เพื่อให้มันใช้งานได้
GeoSword

69

อีกวิธีหนึ่งคือการใช้.( dotคำสั่ง) Iร่วมกับ

  1. เลื่อนเคอร์เซอร์ไปยังตำแหน่งที่คุณต้องการเริ่ม
  2. กด I
  3. พิมพ์คำนำหน้าที่คุณต้องการ (เช่นvendor_)
  4. escกด
  5. กดjเพื่อลงบรรทัด
  6. พิมพ์.เพื่อทำซ้ำการแก้ไขล่าสุดโดยใส่คำนำหน้าอีกครั้งโดยอัตโนมัติ
  7. สลับอย่างรวดเร็วระหว่างjและ.

ผมพบว่าเทคนิคนี้มักจะเป็นเร็วกว่าโหมดบล็อกภาพสำหรับตัวเลขขนาดเล็กของการเพิ่มและมีประโยชน์เพิ่มว่าถ้าคุณไม่จำเป็นต้องแทรกข้อความในบรรทัดเดียวทุกครั้งในช่วงที่คุณได้อย่างง่ายดายสามารถข้ามพวกเขาโดยการกดปุ่มพิเศษj's .

โปรดทราบว่าสำหรับส่วนเพิ่มเติมที่ต่อเนื่องจำนวนมากวิธีการบล็อกหรือมาโครจะมีความเหนือกว่า


ยินดีที่ได้เห็นวิธีการอื่น
Ibn Saeed

ฉันชอบสิ่งนี้เพียงไม่กี่บรรทัด การเรียกใช้ IMO ง่ายขึ้นมาก
Dan Bechard

หลังจากคุณพิมพ์คำนำหน้าที่คุณต้องการคุณไม่จำเป็นต้องกดแป้น Escape หรือไม่?
iamnotsam

41
  1. CtrlVเลือกเส้นที่คุณต้องการปรับเปลี่ยนการใช้
  2. กด:

    • I: แทรกก่อนสิ่งที่เลือก
    • A: ผนวกหลังจากสิ่งที่เลือก
    • c: แทนที่สิ่งที่เลือก
  3. พิมพ์ข้อความใหม่

  4. กดEscเพื่อใช้การเปลี่ยนแปลงกับทุกบรรทัดที่เลือก

4
ยอดเยี่ยม ฉันเพิ่งจะเน้นขั้นตอนสุดท้ายEscสำหรับ noim VIM เหมือนตัวเอง - ฉันใช้เวลาสักครู่เพื่อคิดออกว่าการเปลี่ยนแปลงจะแพร่กระจาย "ภายหลัง"!
Bugs Bunny

1
นิสัยดีไม่รู้เกี่ยวกับตัวเลือก "A" และ "C" ด้วย
hobbes3

ทำไมมันไม่ทำงานv? ฉันสามารถทำได้ด้วยCtrl+V --> Aแต่การvเลือกข้อความไม่ทำงาน - Aต่อท้ายบรรทัดนั้นเท่านั้น พวกเขาทั้งสองเลือกไม่อยู่เหรอ? นอกจากนี้แปลกมาก - Aต่อท้ายบรรทัดถ้าฉันขยายบล็อกภาพไปยังจุดสิ้นสุดของบรรทัด; ไม่เช่นนั้นมันจะต่อท้ายทุกที่ที่บล็อกภาพสิ้นสุดสำหรับแต่ละบรรทัด มันเหมือนมันไม่รู้จักความแตกต่างระหว่างและa A
Alex G

1
ฉันต้องการใช้cแทนCแต่มันใช้ได้ดีอย่างสมบูรณ์ ขอบคุณ
Tarol

29

ฉันจะใช้แมโครเพื่อบันทึกการกระทำของฉันแล้วจะทำซ้ำ

  1. วางเคอร์เซอร์ของคุณบนตัวอักษรตัวแรกใน ชื่อ
  2. ตี qqเพื่อเริ่มการบันทึกลงในบัฟเฟอร์ q
  3. กดiเพื่อเข้าสู่โหมดแทรกให้พิมพ์vector_แล้วกดEscเพื่อออกจากโหมดแทรก
  4. ตอนนี้โดน 0เพื่อกลับไปที่จุดเริ่มต้นของบรรทัด
  5. ตอนนี้โดน jเพื่อลงไป
  6. ตอนนี้โดน qอีกครั้งเพื่อหยุดการบันทึก

ตอนนี้คุณมีมาโครที่ดี

พิมพ์3@qเพื่อเรียกใช้แมโครของคุณสามครั้งเพื่อทำส่วนที่เหลือของบรรทัด


"q" พิเศษ (สำหรับ "มาโครด่วน" หรือไม่)?
Peter Mortensen

แมโครสามารถทำแบบถาวรได้อย่างไร (ทำงานในหลาย ๆ เซสชัน)
Peter Mortensen

@PeterMortensen Vim มีคุณลักษณะที่เรียกว่าเซสชันที่จะยังคงมีบัฟเฟอร์ (และสิ่งอื่น ๆ อีกมากมาย) ที่คุณสามารถดูได้
Brian Neal

27
:%s/^/vendor_/

หรือฉันหายไปบางอย่าง


คุณพลาดข้อเท็จจริงที่ว่าน่าจะเป็นคำบรรยายย่อยในไฟล์ที่มีบรรทัดอื่น ๆ อีกมากมายซึ่งvender_ไม่ต้องการคำนำหน้า
Dan Bechard

9
@dan หากต้องการเฉพาะคำบรรยายคุณสามารถ จำกัด การค้นหาไว้ที่ชุดของหมายเลขบรรทัดเช่น1,4s/^/vendor_/
Brad Koch

1
@BradKoch ที่น่าสนใจ ฉันไม่ได้ตระหนักถึงข้อ จำกัด หมายเลขบรรทัดขอขอบคุณสำหรับสิ่งนั้น
Dan Bechard

8
เป็นที่น่าสนใจ แต่สิ่งที่เป็นจริงมากขึ้นคือการปิดกั้นสายตาเลือกที่มีและประเภทV :มันจะนำหน้านิพจน์ ed :'<,'>ที่ทำให้ ed นำไปใช้กับการเลือกด้วย:'<,'>s/^/vendor_/
Dolanor เท่านั้น

12

อัปเดตเมื่อมกราคม 2559

ในขณะที่คำตอบที่ได้รับการยอมรับเป็นวิธีแก้ปัญหาที่ยอดเยี่ยม แต่นี่คือการกดแป้นพิมพ์ที่น้อยลงเล็กน้อยและปรับให้ดีขึ้นตามหลักการของคำตอบที่ยอมรับ

  1. เลื่อนเคอร์เซอร์ไปในnname
  2. เข้าสู่โหมดบล็อกภาพ ( ctrlv)
  3. กด 3j
  4. Iกด
  5. vendor_พิมพ์
  6. escกด

ภาพประกอบ

หมายเหตุนี่มีการกดแป้นน้อยกว่าคำตอบที่ยอมรับที่มีให้ (เปรียบเทียบขั้นตอนที่ 3) เราแค่นับจำนวนการกระทำของ j ที่จะดำเนินการ

หากคุณเปิดใช้งานหมายเลขบรรทัด (ดังที่แสดงด้านบน) และทราบหมายเลขบรรทัดที่คุณต้องการย้ายไปขั้นตอนที่ 3 สามารถเปลี่ยนเป็น #Gโดยที่ # คือหมายเลขบรรทัดที่ต้องการ

4Gในตัวอย่างข้างต้นของเรานี้จะเป็น อย่างไรก็ตามเมื่อจัดการกับหมายเลขบรรทัดเพียงไม่กี่การนับที่ชัดเจนจะทำงานได้ดี


7

ฉันต้องการที่จะแสดงความคิดเห็นออกมาเป็นจำนวนมากในไฟล์ config บางอย่างบนเซิร์ฟเวอร์ที่มีเพียง vi (ไม่มีนาโน) ดังนั้นวิธีการทางภาพก็ยุ่งยากเช่นกันนี่คือวิธีที่ฉันทำ

  1. เปิดไฟล์ vi file
  2. แสดงหมายเลขบรรทัด:set number!หรือ:set number
  3. จากนั้นใช้หมายเลขบรรทัดเพื่อแทนที่จุดเริ่มต้นของบรรทัดด้วย "#" ได้อย่างไร

:35,77s/^/#/

หมายเหตุ: ตัวเลขมีทั้งบรรทัดตั้งแต่ 35 ถึง 77 ทั้งสองจะถูกแก้ไข

หากต้องการยกเลิกการคอมเม้นท์ / เลิกทำให้ใช้ :35,77s/^#//

หากคุณต้องการเพิ่มคำข้อความเป็นความคิดเห็นหลังจากทุกบรรทัดของรหัสคุณยังสามารถใช้:

:35,77s/$/#test/ (สำหรับภาษาเช่น Python)

:35,77s/;$/;\/\/test/ (สำหรับภาษาเช่น Java)

หน่วยกิต / อ้างอิง:

  1. /unix/84929/uncommenting-multiple-lines-of-code-specified-by-line-numbers-using-vi-or-vim

  2. /unix/120615/how-to-comment-multiple-lines-at-once


นี่เป็นทางออกที่สมบูรณ์แบบสำหรับฉันเพราะฉันมักจะใช้เป็นกลุ่มเล็ก ๆ
JSON C11

7

คุณอาจมีกรณีการใช้งานที่คุณต้องการลบบล็อกข้อความและแทนที่มัน

แบบนี้

Hello World

Hello World

ถึง

Hello Cool

Hello Cool

คุณสามารถเห็นบล็อกเลือก "โลก" ในทั้งสองบรรทัด

พิมพ์cเพื่อการเปลี่ยนแปลง - ตอนนี้คุณจะอยู่ในโหมดแทรก

ใส่สิ่งที่คุณต้องการแล้วกดปุ่ม Escape

ทั้งสองได้รับการสะท้อนในแนวตั้ง มันทำงานเหมือนกับ 'I' ยกเว้นว่ามันจะแทนที่บล็อกด้วยข้อความใหม่แทนที่จะใส่เข้าไป


6

สมมติว่าคุณมีไฟล์นี้:

something

name
comment
phone
email

something else
and more ...

คุณต้องการที่จะเพิ่ม "vendor_" ในหน้า "ชื่อ", "ความคิดเห็น", "โทรศัพท์" และ "อีเมล" ว่าที่พวกเขาปรากฏในแฟ้ม

:%s/\<\(name\|comment\|phone\|email\)\>/vendor_\1/gc

cธงจะแจ้งให้คุณสำหรับการยืนยัน คุณสามารถวางที่ถ้าคุณไม่ต้องการให้


5

ทางเลือกที่สามารถยืดหยุ่นได้มากกว่า:

ตัวอย่าง: เมื่อต้องการป้อนข้อความ XYZ ที่จุดเริ่มต้นของบรรทัด

:%norm IXYZ

เกิดอะไรขึ้นที่นี่

  • % == ดำเนินการในทุกบรรทัด
  • norm == ดำเนินการคีย์ต่อไปนี้ในโหมดปกติ
  • I == ใส่ที่จุดเริ่มต้นของบรรทัด
  • XYZ == ข้อความที่คุณต้องการป้อน

จากนั้นคุณก็กดEnterและมันจะดำเนินการ

เฉพาะคำขอของคุณ:

:%norm Ivendor_

นอกจากนี้คุณยังสามารถเลือกช่วงเฉพาะ:

:2,4norm Ivendor_

หรือดำเนินการผ่านช่วงภาพที่เลือก:

:'<,'>norm Ivendor_

1
เป็นไปได้ไหมที่จะส่งลำดับสำคัญเช่น <Esc> ขณะอยู่ในโหมดแทรก (norm Iabc <ESC>) เพื่อทำสิ่งที่น่าสนใจมากขึ้น?
batbrat

1
@batbrat ฉันเพิ่งคิดออกนี้! คุณสามารถกดctrl-v ctrl-[เพื่อแทรก "esc Esc" ที่ดึงคุณกลับไปที่ "โหมดปกติ" เพื่อจุดประสงค์ของคำสั่งปกติของคุณ ฉันเพิ่งผ่านการทดสอบนี้กับ'<,'>norm Iaa^[ysiw"ที่^[จะหนี Esc
Aubrey Lavigne

4
Use Ctrl+V to enter visual block mode
Move Up/Down to select the columns of text in the lines you want to comment.
Then hit Shift+i and type the text you want to insert.
Then hit Esc, wait 1 second and the inserted text will appear on every line

วิธีนี้ใช้ได้กับ vim ทุกรุ่นหรือต้องการ vim plugin ใด ๆ ? เหตุผลที่ฉันถามคือ b / c บางครั้งมันทำงานบนเครื่องบางอย่าง แต่บางครั้งไม่ได้ ฉันไม่สามารถเข้าใจความแตกต่าง เป็นกลุ่มที่มาพร้อมกับคอมไพล์บน windows - ฉันไม่สามารถทำงานได้ บนเครื่องที่ใช้ Ubuntu และ CentOS Linux ฉันไม่สามารถทำงานได้ ฉันประสบความสำเร็จในบางกรณีที่หายาก แต่ฉันไม่สามารถทำซ้ำความสำเร็จได้ มันเป็นเรื่องลึกลับ ดูเหมือนจะไม่มีอะไรเกิดขึ้นหลังจากฉันกดปุ่ม ESC
davidj411

มันแปลกสำหรับฉันตอนนี้ ไม่มีอะไรเปลี่ยนแปลงยกเว้นดาวบางดวง :) ในขณะที่มองหาวิธีแก้ปัญหาของฉันฉันพบบางอย่างในหน้านี้แม้ว่าจะกล่าวถึงบางสิ่งที่จะมองหาใน vim vim.wikia.com/wiki/Inserting_text_in_multiple_lines ใน Vim ตรวจสอบว่าคุณมี คุณลักษณะตัวดำเนินการ blockwise-I (I, A และอื่น ๆ ) โดยการป้อนคำสั่ง: version ผลลัพธ์ควรมี + visualextra
davidj411

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

2
  1. Ctrl + v เพื่อไปยังโหมดบล็อกภาพ
  2. เลือกบรรทัดโดยใช้ลูกศรขึ้นและลง
  3. ใส่ตัวพิมพ์เล็ก3i(กดตัวพิมพ์เล็ก) Iสามครั้ง)
  4. I กดทุน Iที่จะนำคุณเข้าสู่โหมดแทรก)
  5. เขียนข้อความที่คุณต้องการเพิ่ม
  6. Esc
  7. กดลูกศรลง
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.