ค้นหาธรรมดาและแทนที่เช่น Notepad?
ฉันทราบถึงsubstituteคำสั่งและการใช้งานเป็นคำสั่ง ex:%s/<old>/<new>/g
อย่างไรก็ตามเมื่อ<new>มีสตริงที่ซับซ้อนมากให้พูด URL ที่ซับซ้อนที่มีอักขระจำนวนมากเช่น% [ ] : / \ฯลฯ จากนั้นอักขระจะเริ่มเป็นส่วนหนึ่งของคำสั่ง (โดยเฉพาะ/หรือ:) และฉันต้องเริ่มใช้ลำดับการหลีกเลี่ยงเช่น\
มีวิธีการเปลี่ยนออกทั้งหมดที่จำเป็นสำหรับการหลบหนีและทุกการตีความเพื่อที่ฉันสามารถแทนที่<old>ด้วย<new>แม้ว่า<old>และ<new>มีอักขระ ASCII พลรวมทั้ง/ : [ ] % # $ ( )etc?
ตอนนี้ฉันใช้ Notepad เพื่อทำสิ่งนี้ แต่ฉันหวังว่าฉันจะอยู่ใน VIM ได้
คำตอบ
สมมติว่าไม่มีรูปแบบ\แล้วสิ่งนี้จะใช้ได้:
:%s/\Vpattern/\='string'
ในทุกกรณีเมื่อสตริงรูปแบบและการแทนที่อยู่ในตัวแปรสิ่งนี้จะใช้ได้:
let pattern='<old>'
let str='<new>'
:exec "s/\\V" . escape(escape( pattern, '\'),'/') . "/\\=str"
แน่นอนคุณสามารถใช้วิธีการต่างๆเช่นinput()หรือคำสั่ง args เพื่อตั้งค่าตัวแปร
หลังจากอ่านความคิดเห็นเกี่ยวกับคำตอบแรกของฉันฉันรู้ว่าอาจมีวิธีง่ายๆที่แตกต่างจากคำแนะนำแรกของฉันอย่างมาก คำแนะนำใหม่นี้ยังคงต้องใช้ "เป็นครั้งคราว" ในฐานะสแตนด์อินสำหรับการจับคู่อักขระพิเศษ แต่เนื่องจากไม่มีความสามารถที่แท้จริงในการค้นหาสตริงตามตัวอักษรในกลุ่มคุณจึงต้องประนีประนอมในบางลักษณะ มีฟังก์ชันพิเศษที่คุณสามารถสร้างขึ้นซึ่งอาจเหมาะกับคุณ แต่ฉันพบว่าโซลูชันนี้ใช้งานง่ายและใช้งานง่ายมาก
[เนื่องจากโซลูชันนี้แทบจะไม่มีอะไรเหมือนกันกับโซลูชันแรกของฉันฉันจึงโพสต์ไว้เป็นคำตอบที่สองแทนที่จะเป็นการแก้ไขคำตอบแรกของฉัน ถ้าฉันแก้ไขคำตอบทั้งหมดความคิดเห็นที่เป็นประโยชน์หลายอย่างที่สมาชิกคนอื่น ๆ เพิ่มจะไม่สมเหตุสมผลอีกต่อไป]
คำแนะนำใหม่ของฉันมีดังนี้ ..
ก่อนอื่นฉันวางสิ่งนี้ใน. vimrc ของฉัน ...
set incsearch
จาก:h incsearch...
While typing a search command, show where the pattern, as it was typed
so far, matches. The matched string is highlighted. If the pattern
is invalid or not found, nothing is shown.
[สำหรับตัวอย่างด้านล่างสมมติว่ารูปแบบการค้นหาของคุณเป็นส่วนหนึ่งของคำสั่ง ": global" หรือ ": replace"]
ถ้าคุณต้องการเพื่อให้ตรงกับ URL http:ที่คุณจะเริ่มประเภท ขณะที่คุณพิมพ์โปรดสังเกตว่ารายการที่ตรงกันถัดไปที่เป็นไปได้ในไฟล์ของคุณหรือข้อความที่เลือกจะปรากฏขึ้นและไฮไลต์บนหน้าจอของคุณ เมื่อคุณพิมพ์ตัวอักษรตัวแรก 'h' มันอาจเน้นตัว 'h' ในคำว่า elephant (หาก elephant มี 'h' เป็นครั้งแรกในไฟล์ของคุณหรือในข้อความที่เลือกในปัจจุบัน)
เมื่อคุณพิมพ์ตัวอักษรตัวที่สอง ('t') ตอนนี้สตริงค้นหาของคุณจะเป็น 'ht' และโฟกัสที่ไฮไลต์จะเลื่อนไปที่การจับคู่แรกของ 'ht' สิ่งนี้น่าจะตรงกับ URL มากที่สุด (มีคำว่า "ht" ไม่มากนัก) อาจไม่ใช่ URL ที่คุณกำลังค้นหา แต่คุณยังไม่ได้ป้อนรูปแบบการค้นหาของคุณ
คุณพิมพ์ต่อไป อีกตัว 't' ('htt') ตามด้วย 'p' ('http') และเครื่องหมายทวิภาค ('http:') จนถึงตอนนี้ดีมาก URL แรกยังคงถูกเน้นบนหน้าจอของคุณ มันอาจยังไม่ใช่ URL ที่คุณต้องการ แต่อย่างน้อยคุณก็รู้ว่ารูปแบบของคุณจนถึงตอนนี้ ( http:) ใช้งานได้
แต่ทันทีที่คุณพิมพ์ '/' คุณจะสังเกตเห็นว่าการไฮไลต์ไม่ติดตามสิ่งที่คุณกำลังพิมพ์อีกต่อไป เกิดข้อผิดพลาดในการค้นหา "http: /" คุณอาจลืมไปว่า "/" จำเป็นต้องหนี
แต่คุณไม่จำเป็นต้องจำสิ่งที่ต้องหนี !!!
ความคิดเห็นแบบสดเมื่อไม่ตรงกับ URL อีกต่อไปจะบอกคุณได้ทันทีว่าการเพิ่ม "/" เป็น "http:" จะไม่ตรงกับสิ่งใด ๆ
คุณต้องหนีเครื่องหมาย "/" แต่แทนที่จะหนี '/' ฉันชอบที่จะพิมพ์ตัวเดียว '.' เพราะพิมพ์ง่ายกว่า "\ /" แต่คุณสามารถพิมพ์ "." หรือ '\/'
ข้อเสียของแนวทางนี้คือ (1) ไม่ได้ทำไปโดยสิ้นเชิงกับความจำเป็นในการหลบหนีหรือ '.'; และ (2) ตำแหน่งหน้าจอของคุณอาจเคลื่อนผ่านไฟล์ในขณะที่คุณพิมพ์รูปแบบการค้นหาของคุณ
จากประสบการณ์ของฉันไม่มีใครรบกวนฉัน คุณอาจพบเป็นอย่างอื่น
สำหรับ (1) คุณจะรู้ทันทีเมื่อพิมพ์สิ่งที่ต้องหลีกเลี่ยง ซึ่งจะทำให้การคาดเดาทั้งหมดออกไปจากการสร้างสตริงการค้นหา ฉันพบว่าการประนีประนอมง่ายมากและใช้งานได้ง่ายมาก
สำหรับ (2) ฉันแทบไม่จำเป็นต้องเห็นตำแหน่งดั้งเดิมของฉันในไฟล์ในขณะที่ฉันกำลังพิมพ์สตริงค้นหา ในความเป็นจริงการเคลื่อนไหวแบบสดก่อนหน้าการจับคู่รูปแบบถัดไปและข้อเสนอแนะที่ให้ไว้ในการยืนยันรูปแบบการค้นหาของคุณนั้นถูกต้อง (IMO) เป็นที่นิยมมากกว่า (IMO) มากกว่าเพียงแค่พิมพ์สตริงและหวังว่ามันจะตรงกับสิ่งที่คุณต้องการให้ตรงกัน แต่หากยังคงต้องการดูตำแหน่งเดิมอยู่หน้าจอแยกแนวนอนที่เรียบง่ายควรทำเคล็ดลับ
.vimrc ของฉันมีบรรทัดเหล่านี้ ...
set incsearch
let @o = ".nzz"
map <F8> @o
คำสั่งเหล่านี้ช่วยให้ฉันทำการแก้ไขได้ทุกประเภทโดยไม่ต้องกังวลว่าจะมีอักขระพิเศษอื่น ๆ ออกมา นอกจากนี้ยังช่วยให้ฉันแก้ไขหลายบรรทัดได้อย่างง่ายดาย
เมื่อคำสั่งเหล่านี้อยู่ใน. vimrc ของคุณแล้วขั้นตอนจะเป็นดังนี้ ...
ขั้นแรกคุณต้องค้นหารูปแบบที่ตรงกับเหตุการณ์ทั้งหมดที่คุณต้องการเปลี่ยนแปลง นี่เป็นสิ่งสำคัญเนื่องจากวิธีแก้ปัญหาของฉันขึ้นอยู่กับการย้ายไปยังเหตุการณ์ถัดไปโดยใช้ตัวดำเนินการ find-next ('n')
ตัวอย่างเช่นหากคุณต้องการแก้ไข URL ทั้งหมดจากโฮสต์ "abcxyz.com" ที่ลงท้ายด้วยพูดว่า. php คุณอาจค้นหา (จากโหมดปกติ) ดังนี้ ..
/http:..abcxyz.com.*.php
(... นำหน้า "/" คือสิ่งที่คุณพิมพ์ในโหมดปกติเพื่อเริ่มเข้าสู่รูปแบบการค้นหาฉันใช้อักขระ "//" ใน URL แทนด้วย ".. " เพราะฉันจำไม่ได้ว่า "//" จะ ส่งผลกระทบต่อการดำเนินการค้นหาความสวยงามคือฉันไม่จำเป็นต้องจำตราบใดที่รูปแบบการค้นหาของฉันแม่นยำเพียงพอที่จะจับเหตุการณ์ทั้งหมดที่ฉันต้องการเปลี่ยนแปลงและไม่ตรงกับรูปแบบที่ฉันไม่ต้องการเปลี่ยนแปลงฉันก็ยังดี ไป)
เมื่อคุณกด Enter และอยู่ในตำแหน่งที่เกิดขึ้นครั้งแรกของ URL คุณจะเปลี่ยน URL นั้นตามต้องการด้วยตนเอง ตัวอย่างเช่นหากคุณต้องการเปลี่ยนชื่อโฮสต์จาก "abcxyz.com" เป็น "a111b222.com" คุณสามารถแก้ไขได้โดยพิมพ์ ...
'cfzhttp://a111b222'
.. นี่เป็นเพียงหนึ่งในหลาย ๆ วิธีในการแก้ไข ตรวจสอบให้แน่ใจว่าเป็นการแก้ไขโหมดปกติไม่ใช่การแก้ไขโหมดคำสั่ง
จากนั้นคุณจะไปที่เหตุการณ์ถัดไป ('n')
สุดท้ายยังอยู่ในโหมดปกติคุณต้องป้อนจำนวนเต็มบางส่วนที่เกินจำนวนการเปลี่ยนแปลงที่คุณคิดว่าต้องทำ จำนวนเต็มไม่จำเป็นต้องเป็นจำนวนที่แน่นอนเพียง แต่ต้องมากกว่าจำนวนการเปลี่ยนแปลงเท่านั้น คุณสามารถใช้ 100000000000 ได้หากคุณไม่ทราบว่าต้องทำการเปลี่ยนแปลงจำนวนเท่าใด หากมีการเปลี่ยนแปลงเพียง 20 ครั้งมาโครของฉันจะหยุดหลังจากเกิดเหตุการณ์ที่ 20)
เมื่อคุณพิมพ์จำนวนเต็มขนาดใหญ่แล้ว - อย่ากด ENTER - กด F8 (หรือคีย์ใดก็ตามที่คุณกำหนดมาโครให้)
การดำเนินการนี้จะเปลี่ยนรูปแบบที่เกิดขึ้นทุกครั้งเหมือนกับที่คุณทำด้วยตนเองสำหรับเหตุการณ์แรก
ข้อสันนิษฐานอย่างหนึ่งของการแมปของฉันสมมติคือเมื่อคุณกด F8 เป็นครั้งแรกคุณจะอยู่ในตำแหน่งของไฟล์ในตำแหน่งที่คุณต้องการให้ทำการเปลี่ยนแปลงครั้งแรก
สิ่งที่ดีเกี่ยวกับตัวดำเนินการแก้ไขซ้ำก่อนหน้านี้คือไม่ จำกัด เฉพาะการแก้ไขประเภทใดประเภทหนึ่ง มันสามารถเปลี่ยน 1 อักขระ 1 คำท้ายบรรทัดไปที่จุดเริ่มต้นของบรรทัดทั้งย่อหน้า ฯลฯ
ดังนั้นอีกครั้งแนวคิดก็คือคุณทำการเปลี่ยนแปลงด้วยตนเองเพียงครั้งเดียว - ไม่สำคัญหากคุณเปลี่ยนคำ 5 คำครึ่งบรรทัด 7 บรรทัด ... ตัวดำเนินการแก้ไขซ้ำสุดท้ายจะจำสิ่งนี้ได้
จากนั้นคุณค้นหาเหตุการณ์ถัดไปที่จะเปลี่ยนแปลงตรวจสอบให้แน่ใจว่าเคอร์เซอร์อยู่ในตำแหน่งที่เหมาะสม (เช่นหากคุณกำลังเปลี่ยน URL ทั้งหมดตรวจสอบให้แน่ใจว่าเคอร์เซอร์อยู่ที่จุดเริ่มต้นของ "http: //" แทนที่จะอยู่ใน ตรงกลางของ URL) จากนั้นกด 10000F8
เปลี่ยนจำนวนเต็มให้สูงขึ้นหากคุณมีเหตุการณ์มากกว่า 10,000 ครั้ง
ข้อเสียคือประสิทธิภาพ แต่นั่นจะกลายเป็นปัญหาเมื่อคุณมีการแก้ไขจำนวนมากอย่างแท้จริง (สำหรับฉันการเปลี่ยนแปลงมากกว่า 10,000 รายการอาจช้า แต่ก็พอทนได้มากกว่า 100,000 รายการอาจใช้เวลานานมากและขอแนะนำให้เปลี่ยนกลับไปที่: s - แต่ระยะทางของคุณอาจ แตกต่างกันไป)
ข้อเสียอีกอย่างตามที่คนอื่นชี้ให้เห็นคือฉันไม่ได้ใช้สัญลักษณ์แทนแม้ว่าฉันจะหนีไปแล้วก็ตาม แต่การค้นหาสิ่งที่ต้องใช้สัญลักษณ์แทนนั้นง่ายมากหากset incsearchอยู่ใน vimrc ของคุณ คุณลักษณะนี้จะไฮไลต์ข้อความที่ตรงกันเมื่อคุณพิมพ์รูปแบบการค้นหาของคุณ เมื่อข้อเสนอแนะสดหยุดเน้นสิ่งใด ๆ คุณจะรู้ว่ารูปแบบของคุณไม่ถูกต้องซึ่งมักเกิดจากอักขระที่ต้องใช้ Escape ฉันชอบแทนที่อักขระด้วย "." เป็นตัวยึดตำแหน่งที่จับทั้งหมด (เพียงเพราะฉันคิดว่ามันง่ายกว่าที่จะพิมพ์ แต่การใช้ Escape ก็ใช้ได้เช่นกัน)
การใช้งานและการทำซ้ำกับcgn.
ขั้นแรกค้นหาสตริง "เก่า" ด้วย
/.cgnถัดไปตี สิ่งนี้จะแทนที่เหตุการณ์ถัดไปของ 'old' และทำให้คุณอยู่ในโหมดแทรกพิมพ์ข้อความแทนที่ 'ใหม่' และกด
Escเมื่อเสร็จสิ้นทำซ้ำสำหรับเหตุการณ์อื่น ๆ ทั้งหมดของ 'เก่า'
[count].ด้วย
แนวคิดคือการพิมพ์สตริงการแทนที่ 'ใหม่' ในโหมดการแทรกที่ดีเพื่อที่เราจะได้ไม่ต้องกังวลกับการหลีกเลี่ยงอักขระพิเศษ
สำหรับ[count]จำนวนมาก ๆ จะเพียงพอ หรือหาจำนวนของการเกิดขึ้นของ 'เก่า' :%sgnกับ
(สำหรับอักขระพิเศษใน 'old' สิ่งที่ดีที่สุดที่ฉันคิดได้คือ/\V<old>คุณยังคงต้องหนี\และ/อย่างไรก็ตาม)