ค้นหาและแทนที่สตริงในกลุ่มหลายบรรทัด


354

ฉันสามารถทำได้:%s/<search_string>/<replace_string>/gเพื่อแทนที่สตริงข้ามไฟล์หรือ:s/<search_string>/<replace_string>/เพื่อแทนที่ในบรรทัดปัจจุบัน

ฉันจะเลือกและแทนที่คำจากบรรทัดที่เลือกเป็นกลุ่มได้อย่างไร?

ตัวอย่าง: แทนที่ข้อความจากเส้น6-10, แต่ไม่ได้มาจาก14-1811-13



คำตอบ:


255

:&&คำสั่งซ้ำการเปลี่ยนตัวผู้เล่นที่ผ่านมากับธงเดียวกัน คุณสามารถจัดหาช่วงเพิ่มเติมให้กับมัน (และเชื่อมต่อได้มากเท่าที่คุณต้องการ):

:6,10s/<search_string>/<replace_string>/g | 14,18&&

หากคุณมีหลายช่วงฉันควรใช้การวนซ้ำ:

:for range in split('6,10 14,18')| exe range 's/<search_string>/<replace_string>/g' | endfor

5
ขอบคุณ หมายเหตุสำหรับผู้ใช้ในอนาคต - :6,10s/<search_string>/<replace_string>/g | :14,18&& | :20,23&& | :28,31&&จะใช้งานได้, forลูปทำให้ง่ายต่อการจดจำและดำเนินการ
mu 無

5
ดีใจที่คุณชอบมัน! :ในคำสั่งที่ตามมาเป็นตัวเลือกครับเพื่อให้คุณสามารถบันทึกการกดแป้นพิมพ์บางมากขึ้น
Ingo Karkat

2
:&&จะช่วยฉันกดแป้นพิมพ์หลายร้อยครั้งต่อสัปดาห์ ขอบคุณ!
pdoherty926

มันทำงานได้โดยไม่ต้อง 'g' ในตอนท้ายในกลุ่มของฉัน ดังนั้นเมื่อคุณระบุช่วงของเส้นมันไม่จำเป็นต้องใช้ค่าสถานะโกลบอล
Tayyar R

3
@TayyarR ช่วงครอบคลุมบรรทัด (แนวตั้งเพื่อพูด) ในขณะที่ธง 'g' กำหนดว่าการแข่งขันเพียงหนึ่งหรือทั้งหมดภายในบรรทัด (ดังนั้นแนวนอน) จะถูกแทนที่
Ingo Karkat

389

แทนที่ทั้งหมด:

:%s/foo/bar/g

ค้นหาการเกิดขึ้นของ 'foo' (ในทุกบรรทัด) และแทนที่ด้วย 'bar'

สำหรับบรรทัดเฉพาะ:

:6,10s/foo/bar/g

เปลี่ยน 'foo' เป็น 'bar' สำหรับทุกบรรทัดจากบรรทัด 6 เป็น 10


4
จุดประสงค์ของ / g ที่นี่คืออะไร ขออภัยฉันใหม่กับ linux
Raja Anbazhagan

4
@RajaAnbazhagan ส่วนสุดท้ายของการแสดงออกนี้หลังจากที่ผ่าน/มาเป็นที่ที่คุณระบุธงสำหรับการดำเนินการ คำสั่งนี้โดยปกติจะแทนที่การแข่งขันครั้งแรกในบรรทัด; ด้วยการgตั้งค่าสถานะมันจะแทนที่สิ่งที่เกิดขึ้นทั้งหมด
Litty

17
คุณควรอ้างอิงแหล่งข้อมูลของคุณจริงๆ (เช่น vim.wikia.com/wiki/Search_and_replace) หากคุณกำลังจะคัดลอกและผ่านงานของบุคคลอื่น
Andrew S

2
%สิ่งที่ไม่ทำงาน! มิฉะนั้นจะเกิดขึ้นเพียงครั้งแรกเท่านั้น
Santosh Kumar

8
%=> เรียกใช้คำสั่งนี้ในทุกบรรทัด g=> จับคู่เหตุการณ์ที่เกิดขึ้นหลายรายการในบรรทัดเดียวกัน
Shaahiin

55

ในฐานะที่เป็นบันทึกย่อด้านข้างแทนที่จะต้องพิมพ์หมายเลขบรรทัดเพียงแค่ไฮไลต์บรรทัดที่คุณต้องการค้นหา / แทนที่ในหนึ่งในโหมดภาพ:

  • VISUALโหมด ( V)
  • VISUAL BLOCKโหมด ( Ctrl+ V)
  • VISUAL LINEโหมด ( Shift+ Vทำงานได้ดีที่สุดในกรณีของคุณ)

เมื่อคุณเลือกบรรทัดเพื่อแทนที่ให้พิมพ์คำสั่งของคุณ:

:s/<search_string>/<replace_string>/g

คุณจะทราบว่าช่วง'<,'>จะถูกแทรกโดยอัตโนมัติสำหรับคุณ:

:'<,'>s/<search_string>/<replace_string>/g

นี่'<ก็หมายความว่าเส้นไฮไลต์ครั้งแรกและ'>วิธีสุดท้ายที่เส้นไฮไลต์

โปรดทราบว่าลักษณะการทำงานอาจไม่คาดคิดเมื่ออยู่ในNORMALโหมด: '<และ'>ชี้ไปที่จุดเริ่มต้นและจุดสิ้นสุดของไฮไลต์สุดท้ายที่ทำในVISUALโหมดใดโหมดหนึ่ง แต่ในNORMALโหมดหมายเลขบรรทัดพิเศษ.สามารถนำมาใช้ซึ่งก็หมายถึงบรรทัดปัจจุบัน ดังนั้นคุณสามารถค้นหา / แทนที่เฉพาะในบรรทัดปัจจุบันเช่นนี้:

:.s/<search_string>/<replace_string>/g

สิ่งที่ควรทราบอีกประการหนึ่งคือการแทรกช่วงที่สอง:ระหว่างช่วงและคำสั่ง find / replace ไม่มีอันตรายใด ๆ กล่าวคือคำสั่งเหล่านี้ยังคงใช้งานได้:

:'<,'>:s/<search_string>/<replace_string>/g
:.:s/<search_string>/<replace_string>/g

1
> ตัวอย่าง: แทนที่ข้อความจากบรรทัด 6-10, 14-18 แต่ไม่ใช่จาก 11-13 - คำตอบของคุณไม่ได้ตอบคำถามนี้ใช่ไหม?
poige

27

คุณสามารถทำได้ด้วยสองลำดับการค้นหา / แทนที่

  :6,10s/<search_string>/<replace_string>/g
  :14,18s/<search_string>/<replace_string>/g

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


21

ในกลุ่มถ้าคุณสับสนว่าทุกบรรทัดจะได้รับผลกระทบใช้ด้านล่าง

 :%s/foo/bar/gc  

เปลี่ยน 'foo' เป็น 'bar' แต่ละอัน แต่ขอให้ยืนยันก่อน กด 'y' สำหรับใช่และ 'n' เพื่อไม่ อย่าลืมที่จะบันทึกหลังจากนั้น

:wq

2
คุณสามารถใช้การcตั้งค่าสถานะเพิ่มเติมนอกเหนือจากการระบุช่วง:6,10s/<search_string>/<replace_string>/cได้ ย่อมาจากc confirmฉันใช้cธงค่อนข้างบ่อยเพื่อป้องกันการแทนที่คำโดยไม่ได้ตั้งใจซึ่งฉันไม่ได้คิดเกี่ยวกับว่ามีอยู่ด้วย
Wolfson

16

VI ค้นหาและแทนที่ตัวอย่างคำสั่ง

ให้เราบอกว่าคุณต้องการค้นหาคำที่เรียกว่า "foo" และแทนที่ด้วย "bar"

ตีครั้งแรก[Esc]ที่สำคัญ

ประเภท: (โคลอน) ตามด้วย%s/foo/bar/และกดปุ่ม [Enter]

:%s/foo/bar/


11
:%s/<search_string>/<replace_string>/gคำสั่งของคุณจะแทนที่สิ่งที่เกิดขึ้นทั้งหมดในไฟล์ทั้งหมด ไม่ว่าคำตอบของคำถามที่ว่า แต่มีประโยชน์กระนั้น :)
tanius

@tanius จริงๆแล้วมันเป็นคำตอบที่ตรงไปตรงมาที่สุดสำหรับปัญหาของฉัน คุณสามารถลองปรับเปลี่ยนคำถามเป็น "ค้นหาและแทนที่สตริงเป็นกลุ่มบน" เลือก "บรรทัด"
Omid N

9

เราไม่จำเป็นต้องป้อนหมายเลขบรรทัดปัจจุบัน

หากคุณต้องการเปลี่ยนfooเป็นbarบรรทัดปัจจุบัน ( .) และสองบรรทัดถัดไป ( +2) เพียงทำ:

:.,+2s/foo/bar/g

หากคุณต้องการยืนยันก่อนที่จะทำการเปลี่ยนแปลงให้แทนที่gด้วยgc:

:.,+2s/foo/bar/gc

อีกสิ่งที่ดีที่ฉันมักใช้คือ:.,$s/foo/bar/gcการค้นหาและแทนที่เริ่มต้นจากบรรทัดปัจจุบันจนถึงจุดสิ้นสุดของไฟล์
Wolfson

3

ค้นหาและแทนที่

:%s/search\|search2\|search3/replace/gci

g => การค้นหาทั่วโลก

c => ขอคำยืนยันก่อน

i => กรณีตาย

หากคุณต้องการเปลี่ยนโดยตรงโดยไม่ต้องยืนยันให้ใช้คำสั่งด้านล่าง

:%s/search/replace/g

หากคุณต้องการการยืนยันสำหรับการแทนที่แต่ละรายการให้รันคำสั่งด้านล่าง

:%s/search/replace/gc

ขอคำยืนยันก่อนการค้นหาที่นี่จะเป็นแบบตัวเล็ก

:%s/search/replace/gci

1

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

สิ่งนี้ไม่สามารถทำได้ผ่านคำสั่ง vim มาตรฐาน คุณสามารถใช้วิธีการแก้ปัญหาด้วยการใช้! (ตัวกรอง) ตัวดำเนินการและวัตถุข้อความใด ๆ ตัวอย่างเช่นหากต้องการใช้การดำเนินการกับย่อหน้าคุณสามารถทำสิ่งต่อไปนี้

!ip

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

1
2  Repellendus qui velit vel ullam!
3  ipsam sint modi! velit ipsam sint
4  modi! Debitis dolorum distinctio
5  mollitia vel ullam! Repellendus qui
6  Debitis dolorum distinctio mollitia
7  vel ullam! ipsam
8
9  More text around here

ผลลัพธ์หลังจากกดปุ่ม "! ap" จะเป็นดังนี้:

:.,.+5

ในฐานะ '.' (จุด) หมายถึงบรรทัดปัจจุบันช่วงระหว่างบรรทัดปัจจุบันและ 5 บรรทัดหลังจากนั้นจะถูกใช้สำหรับการดำเนินการ ตอนนี้คุณสามารถเพิ่มคำสั่งทดแทนแบบเดียวกับก่อนหน้านี้

ส่วนที่ไม่ดีคือการเลือกข้อความเพื่อใช้ตัวดำเนินการในภายหลังนั้นไม่ใช่เรื่องง่าย ส่วนที่ดีคือสิ่งนี้สามารถทำซ้ำการแทรกช่วงสำหรับช่วงข้อความอื่น ๆ ที่คล้ายกัน (ในกรณีนี้ย่อหน้า) ที่มีขนาดแตกต่างกัน คือถ้าคุณต้องการเลือกช่วงที่ใหญ่กว่าวรรค '.' จะไปทางขวา

นอกจากนี้หากคุณชอบความคิดในการใช้วัตถุข้อความความหมายเพื่อเลือกช่วงของการดำเนินการคุณสามารถตรวจสอบปลั๊กอินของฉัน EXtend.vimที่สามารถทำเช่นเดียวกัน แต่ในลักษณะที่ง่ายขึ้น


0

ในการตอบคำถามนี้:

:40,50s/foo/bar/g

แทนที่ foo ด้วยแถบในบรรทัดเหล่านี้ระหว่างบรรทัดที่ 40 และบรรทัดที่ 50 (รวม) เมื่อเรียกใช้คำสั่งนี้คุณสามารถอยู่ในบรรทัดใดก็ได้

:50,40s/foo/bar/g

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

:,50s/foo/bar/g

แทนที่ foo ด้วยแถบในบรรทัดเหล่านี้ระหว่างบรรทัดที่คุณอยู่ในปัจจุบันและบรรทัดที่ 50 (รวม) (หากคุณอยู่ในสายหลังจากที่กลุ่มที่ 50 จะขอยืนยันอีกครั้ง)

ในการล้างความแตกต่างระหว่าง vim และปลั๊กอิน vrapper ของ Eclipse:

โปรดทราบว่าใน varpper

:,50s/foo/bar/g คำสั่งจะไม่ทำงาน

:50,40s/foo/bar/g จะทำงานโดยไม่ต้องยืนยันการยืนยัน

(สำหรับ Vrapper เวอร์ชั่น 0.74.0 ขึ้นไป)


-5
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal

สมมติว่าคุณต้องการแทนที่ข้างต้นด้วยข้อมูลอื่น

COMMAND(:%s/\/sys\/sim\/source\/gm\/kg\/jl\/ls\/owow\/lsal/sys.pkg.mpu.umc.kdk./g)

ในส่วนนี้จะถูกแทนที่ด้วย ( sys.pkg.mpu.umc.kdk.)


ฉันไม่แน่ใจว่าสิ่งนี้ตอบคำถามได้จริง จากคำถามปรากฏว่าผู้ขอทราบได้ตระหนักถึงวิธีการใช้%sเพื่อแก้ไขอินพุต แต่ต้องการทราบวิธีการทำ "กึ่งทั่วโลก" (เช่นสเปคของเขาคือบรรทัด 6-10 และ 14-18 แต่ไม่ใช่ในบรรทัดที่ 11 - 13)
Brandon Buck

1
นอกจากนี้ "คำสั่ง" คืออะไร? และคุณกำลังทุกข์ทรมานจากโรคไม้จิ้มฟันที่พิงอยู่
Martin Tournoij

ในการรักษากลุ่มอาการของโรคที่คุณสามารถใช้ตัวอักษรอีกเป็นตัวคั่นแทนการเริ่มต้น/เช่น!, @, _::%s_/sys/sim/source/gm/kg/jl/ls/owow/lsal_sys.pkg.mpu.umc.kdk_g
MortezaE
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.