บรรทัดที่ซ้ำกันที่ขึ้นต้นด้วย“ x” แทนที่“ x” ในบรรทัดที่ซ้ำกันด้วย“ y” หรือไม่


9

ฉันมีไฟล์ที่มีรูปแบบต่อไปนี้:

foo 111
baz
foo 222
baz
foo 333
baz

ซึ่งต้องเปลี่ยนเป็น

foo 111
bar 111
baz
foo 222
bar 222
baz
foo 333
bar 333
baz

ดังนั้นทำซ้ำทุกบรรทัดที่ขึ้นต้นด้วยfooและเปลี่ยนแปลงเฉพาะfooในซ้ำ แต่ปล่อยให้ส่วนที่เหลือของบรรทัด (ซึ่งแตกต่างกันในแต่ละกรณี) เหมือนเดิม ทำอย่างไร


หากคุณไม่ได้ตกนรกบน regexp มาโครจะทำได้ดี ไม่สำคัญมากในกรณีง่าย ๆ เช่นนี้ แต่ถ้าคุณมีบางอย่างที่ซับซ้อนกว่านี้มันเป็นทางเลือกที่ถูกต้องมาก
PhilippFrank

คำตอบ:


19

ไปเลย:

:g/foo/t.|s//bar

เน่าเฟะ:

:g/foo/    " start a global command applied on all lines matching 'foo'
t.         " duplicate the current line (the cursor is now on the new line)
|          " chain a new command
s//bar     " substitute the last searched element with 'bar'

เนื่องจากgคำสั่งจะอัพเดตรูปแบบการค้นหาดังนั้นคุณสามารถละเว้นรูปแบบที่จะแทนที่ในคำสั่งแทนที่ (การอ้างอิง: :h :gค้นหาsearch pattern)


รุ่นเก่ากว่า:

:g/foo/norm! yyp:s/foo/bar^M

เน่าเฟะ:

:g            start a global command
/foo/         apply only on lines having 'foo'
norm!         execute a normal command
yyp           duplicate the line
:s//bar       replace foo with bar on the line (the duplicated one)
^M            add enter to execute the substitution

เพื่อแทรก^MกดและCtrl+venter

หมายเหตุ : ฉันมากับรุ่น "เก่ากว่า" ก่อนที่ฉันจะเรียนรู้เกี่ยวกับtคำสั่ง ฉันจะทิ้งไว้ แต่ฉันจะไม่แนะนำให้ใช้ อันแรกสะอาดกว่าตรงไปตรงมามากกว่า


แก้ไขได้แล้ว 'เวอร์ชั่นที่ง่ายกว่า' ทำงานได้อย่างสมบูรณ์ อย่างไรก็ตามเวอร์ชันแรกส่งผลให้บรรทัดที่ซ้ำกันยังคงขึ้นต้นด้วยfoo....
LB7979

แปลกประหลาดคุณป้อน^Mตามที่อธิบายไว้หรือไม่
nobe4

ฉันไม่ดีอ่านไม่ออก วิธีแก้ปัญหาแรกก็ใช้ได้เช่นกัน!
LB7979

ฉันไม่รู้ว่าทำไมคุณถึงรบกวนรุ่นที่ซับซ้อนด้วย เวอร์ชันที่ง่ายกว่าคือ ... เรียบง่ายขึ้น ;) (ไม่ต้องพูดถึงว่าเป็นไปตาม POSIX) ทำไมไม่ใส่ก่อน?
Wildcard

1
ตอนแรกฉันมากับรุ่นแรกซึ่งเป็นธรรมชาติมากขึ้นสำหรับฉันเพราะในเวลาที่ฉันไม่ได้ตระหนักถึงtและจากนั้นฉันเพิ่มรุ่นที่สอง ฉันจะเปลี่ยนคำสั่งคุณถูกต้อง สิ่งแรกเกี่ยวกับ POSIX เป็นอย่างไร
nobe4

1

ฉันทำสิ่งนี้ตลอดเวลาและทำสิ่งที่ชอบ%s/^foo \(.*\)/foo \1\rbar \1/(บางส่วนเพราะฉันยังทำงานที่คล้ายกันมากมายซึ่งไม่สามารถกลายเป็นสิ่งที่ฉลาดโดยใช้ฟังก์ชั่นการคัดลอกและตอน\(.*\)นี้เป็นส่วนหนึ่งของหน่วยความจำกล้ามเนื้อของฉัน)

ฉันสงสัยว่ามันไม่ตรงตามมาตรฐาน POSIX (ไม่สามารถใช้กับโคลน vi อื่น ๆ ได้) แต่ใช้^M( C-VReturn) แทนที่จะ\rดูเหมือนว่าจะทำงานกับโคลน vi อื่น ๆ ส่วนใหญ่

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