ค้นหาและแทนที่เป็นกลุ่มในบรรทัดเฉพาะ


95

ฉันสามารถใช้

:5,12s/foo/bar/g

เพื่อค้นหาfooและแทนที่barระหว่างบรรทัดที่ 5 และ 12 ฉันจะทำสิ่งนั้นเฉพาะในบรรทัดที่ 5 และ 12 ได้อย่างไร (และไม่อยู่ในระหว่างบรรทัด)

คำตอบ:


76

Vim มีอะตอมของนิพจน์ทั่วไปพิเศษที่ตรงกับบรรทัดคอลัมน์ ฯลฯ คุณสามารถใช้ (อาจนอกเหนือจากช่วง) เพื่อ จำกัด การแข่งขัน:

:5,12s/\(\%5l\|\%12l\)foo/bar/g

ดู :help /\%l


8
วิธีที่ซับซ้อนกว่าที่ฉันคาดไว้ แต่ตอบคำถามของฉันได้อย่างสมบูรณ์แบบ ขอบคุณ!
pfnuesel

56

คุณสามารถทำการเปลี่ยนตัวในบรรทัดที่ 5 และทำซ้ำโดยใช้ความพยายามเพียงเล็กน้อยในบรรทัดที่ 12:

:5s/foo/bar
:12&

ตามที่ Ingo ชี้ไว้ให้:&ลืมธงของคุณ เนื่องจากคุณใช้/gคำสั่งที่ถูกต้องจะเป็น:&&:

:5s/foo/bar/g
:12&&

ดู:help :&และเพื่อน.


10
+1 สำหรับใส่สิ่งที่คลุมเครือ:&เพื่อใช้งาน หากมีแฟล็ก ( s/../../g) ต้องใช้:&&แม้ว่า ...
Ingo Karkat

10
@IngoKarkat เพื่อความเป็นธรรมฉันคิดว่า\(\%5l\|\%12l\)คลุมเครือมากกว่า:&
doubleDown

13

คุณสามารถเพิ่ม a cต่อท้ายได้เสมอ สิ่งนี้จะขอการยืนยันสำหรับการแข่งขันแต่ละครั้ง

:5,12s/foo/bar/gc

1
นี่อาจเป็นฝันร้ายหากมีการแข่งขันระหว่างบรรทัดที่ 5 และ 12 จำนวนมาก (โปรดทราบว่ามีgธงอยู่ในการเล่น)
doubleDown

1
@doubleDown นี่ไม่ได้หมายความว่าจะเป็นวิธีแก้ปัญหาแบบสากล (ซึ่งมีผู้สมัครที่เป็นไปได้จำนวนมาก) แต่ในกรณีส่วนใหญ่คุณคิดว่าการกดn5 หรือ 6 ครั้งเป็นเรื่องยุ่งยากมากกว่าการเพิ่ม\(\%5l\|\%12l\)คำสั่งแทน
คณบดี

ฉันพบว่าสิ่งนี้มีประโยชน์ฉันต้องการเปลี่ยนทุก ๆ บรรทัดสิ่งนี้น่าจะเร็วกว่าสิ่งที่ฉันทำ
tiktak

9

คำถามที่น่าสนใจ ดูเหมือนว่าจะมีเฉพาะการเลือกช่วงและไม่มีการเลือกหลายบรรทัด:

http://vim.wikia.com/wiki/Ranges

อย่างไรก็ตามหากคุณมีสิ่งพิเศษในบรรทัดที่ 5 และ 12 คุณสามารถใช้ตัว:gดำเนินการได้ หากไฟล์ของคุณมีลักษณะเช่นนี้ (ตัวเลขสำหรับอ้างอิงเท่านั้น):

 1     line one
 2     line one
 3     line one
 4     line one
 5     enil one
 6     line one
 7     line one
 8     line one
 9     line one
10     line one
11     line one
12     enil one

และคุณต้องการแทนที่oneด้วยenoบนเส้นที่มีenilแทนline:

:g/enil/s/one/eno/

5
นี่เป็นเรื่องสมมติมาก
doubleDown

1

คุณสามารถใช้ed- โปรแกรมแก้ไขข้อความเชิงบรรทัดที่มีคำสั่งคล้ายกับ vi และ vim มันอาจเกิดขึ้นก่อน VI และ Vim

ในสคริปต์ (โดยใช้เอกสารที่นี่ซึ่งประมวลผลอินพุตจนถึงเครื่องหมาย EndCommand) จะมีลักษณะดังนี้:

ed file <<EndCommands
    5
    s/foo/bar/g
    7
    s/foo/bar/g
    wq
EndCommands

เห็นได้ชัดว่าคำสั่ง ed สามารถใช้กับบรรทัดคำสั่งได้เช่นกัน


3
ฉันไม่เห็นข้อได้เปรียบเหนือvimทางเลือกอื่น
Bernhard

1
และสามารถทำได้ด้วย Vim เช่นกัน ตัวเลขสามารถใส่ไว้ข้างหน้าได้:sแต่ยังคงมีการทำซ้ำของ:sคำสั่ง (ซึ่งโซลูชันของ romainl หลีกเลี่ยง)
Ingo Karkat

มุมมองของฉันคือผู้ใช้อาจต้องการเลือกมากกว่าสองบรรทัดสำหรับการแก้ไข ในกรณีนี้แนวทางที่ไม่โต้ตอบอาจเป็นที่สนใจซึ่ง AFAIK ไม่สามารถทำได้ด้วยกลุ่ม
สงสัย

1
โอ้ Vim สามารถทำได้ (เช่นในโหมด "Ex") แต่คุณคิดถูกที่ควรเลือกใช้เครื่องมืออื่นมากกว่าโปรแกรมแก้ไขแบบโต้ตอบ ความชอบของฉันsedคือ ...
Ingo Karkat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.