วิธีคัดลอกแต่ละบรรทัด 11 ครั้งโดยเพิ่ม“ 1” ครั้งสุดท้ายในแต่ละบรรทัดตั้งแต่ 2-12


9

ฉันมีจำนวนบรรทัดในไฟล์และฉันต้องการคัดลอกแต่ละบรรทัด 11 ครั้ง (เปลี่ยนแต่ละบรรทัดเป็น 12 บรรทัด) และเพิ่ม "1" สุดท้ายในแต่ละบรรทัดเพื่อให้ 12 บรรทัดมี "1" ถึง " 12 "โดยที่" 1 "เริ่มแรกคือ อาจมีเหตุการณ์อื่นเกิดขึ้นเป็น "1" ในแต่ละบรรทัด แต่ "1" ที่ฉันต้องการเพิ่มจะเป็นเหตุการณ์สุดท้ายในแต่ละบรรทัดเสมอ อีกวิธีในการดูคือ "1" สุดท้ายจะอยู่หลัง "/ nt /" - เหมือนใน "/ nt / 1" (และจะเป็น "/ nt / 1" เท่านั้นในแต่ละบรรทัด) .

ตัวอย่างเช่นถ้าฉันมี:

1stlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/1blah
3rdlineblahblahblah/nt/1blah

ฉันต้องการเปลี่ยนเป็น:

1stlineblahblahblah/nt/1blah
1stlineblahblahblah/nt/2blah
1stlineblahblahblah/nt/3blah
1stlineblahblahblah/nt/4blah
1stlineblahblahblah/nt/5blah
1stlineblahblahblah/nt/6blah
1stlineblahblahblah/nt/7blah
1stlineblahblahblah/nt/8blah
1stlineblahblahblah/nt/9blah
1stlineblahblahblah/nt/10blah
1stlineblahblahblah/nt/11blah
1stlineblahblahblah/nt/12blah
2ndlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/3blah
...

ก่อนหน้านี้ฉันได้พบคำสั่ง:

:for i in range(0,12) | put ='1stlineblahblahblah/nt/'.i.'blah' | endfor

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

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

คำตอบ:


8

นี่คือการทดแทนที่แก้ปัญหา:

:%s/\(.*\)1\(.*\)/\=join(map(range(1, 12), 'submatch(1) . v:val . submatch(2)'), "\n")

การทดแทนตรงกับแต่ละบรรทัดที่มี "1" และจับข้อความก่อน{c1}และหลัง{c2}"1" ครั้งสุดท้าย สำหรับสายที่ตรงกับแต่ละช่วงของตัวเลข 1-12 {n}จะแมป{c1}{n}{c2}เพื่อสร้างสิบสองเส้นของรูปแบบ แต่ละกลุ่มสิบสองบรรทัดจะแทนที่บรรทัดที่จับคู่กัน

:h sub-replace-expressionดู


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

10

คุณสามารถทำได้โดย

  1. บันทึกแมโครแล้ว
  2. การใช้globalคำสั่ง ex เพื่อเรียกใช้แมโครnจำนวนครั้งสำหรับแต่ละบรรทัดในไฟล์

หลังจากบันทึกแมโครให้ยกเลิกการเปลี่ยนแปลงที่ทำขณะบันทึกหรือจะมีn + 1บรรทัดเพิ่มเติมสำหรับบรรทัดแรกและnสำหรับบรรทัดที่ต่อเนื่องกัน

บันทึกแมโครaลงทะเบียนด้วย

qayyp$?\d<CR><C-A>q

บันทึกนี้ลงทะเบียนa( qa...q) คำสั่งต่อไปนี้:

  • yyp: ทำซ้ำบรรทัดปัจจุบัน
  • $: เลื่อนไปที่ท้ายบรรทัด
  • ?\d<CR>: ค้นหาย้อนหลังด้วยตัวเลขหนึ่งหลัก
  • <C-A>: ตัวเลขที่เพิ่มขึ้นภายใต้เคอร์เซอร์หนึ่ง

เมื่อบันทึกแมโครแล้วให้ลบการเปลี่ยนแปลงที่ทำในขณะที่บันทึกไว้โดยการเลิกทำ ( uu) หรือลบบรรทัดปัจจุบัน ( dd) จากนั้นทำซ้ำแมโคร11(หรือจำนวนเท่าใดก็ได้) สำหรับแต่ละบรรทัดในไฟล์ด้วยคำสั่งโกลบอล:

:g//normal 11@a

2
มันได้ผล! ดีมากขอบคุณ ฉันมีปัญหาในตอนแรกกับ Ctrl-a ที่เน้นทุกอย่างแทนการเพิ่มเพราะฉันใช้ gVim ใน Windows ... แต่ฉันทำการค้นหาอย่างรวดเร็วและพบกระทู้นี้ - stackoverflow.com/questions/289681/ … - ที่ที่ฉันอยู่ ใช้คำแนะนำในการวาง nnoremap <kPlus> <Ca> nnoremap <kMinus> <Cx> ใน _vimrc เพื่อให้ฉันสามารถใช้ปุ่ม "+" และ "-" เพื่อเพิ่มและลบ นอกจากนี้คำสั่งทั่วโลกจำเป็นต้องเป็น: g // ปกติ 11 @ a สำหรับฉัน แต่นั่นก็คิดออกได้ง่าย ขอบคุณ!
canwasiereisawelba

6

สองทาง:

ใช้มาโคร!

เริ่มด้วย

1stlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/1blah
3rdlineblahblahblah/nt/1blah

ด้วยเคอร์เซอร์ของคุณในบรรทัดแรก

qqyyp$?\d<CR><Ctrl-a>q
10@q

ซึ่งทำ:

qq เริ่มบันทึกแมโครลงใน q register

yyp ดึงบรรทัดปัจจุบันแล้ววางลงด้านล่าง

$?\d<CR> ไปที่ท้ายบรรทัดแล้วค้นหาตัวเลขตัวแรกที่มองย้อนกลับไป

<Ctrl-a> เพิ่มจำนวน

q หยุดการบันทึกแมโคร

สิ่งนี้ทำให้คุณมี:

1stlineblahblahblah/nt/1blah
1stlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/3blah

ด้วยเคอร์เซอร์บนบรรทัดที่สอง เพียงทำซ้ำแมโครนี้หลาย ๆ ครั้งตามที่ต้องการ (ตัวอย่างเช่นทำซ้ำสิบครั้งด้วย 10 @ q) หากคุณต้องการทำให้กระบวนการนี้เป็นไปโดยอัตโนมัติสำหรับแต่ละบรรทัดให้ดำเนินการแบบโกลบอลกับแต่ละบรรทัด:

:g//normal 11@q

อีกทางเลือกหนึ่งที่มีรุ่นใหม่ที่เป็นกลุ่ม: วางโฆษณาที่คุณต้องการ g <Ctrl-a>แต่หลายครั้งบล็อกภาพเลือกหลักที่คุณต้องการที่จะเพิ่มขึ้นและกด สิ่งนี้จะเพิ่มจำนวนทั้งหมดในบล็อกภาพตามที่คุณต้องการ อย่างไรก็ตามนี่เป็นกระบวนการที่ต้องดำเนินการด้วยตนเองมากกว่า


1
เยี่ยมมากฉันไม่รู้เกี่ยวกับg <c-a>วิธีการ ขอบคุณสำหรับการแบ่งปัน.
kba ย่อมาจาก Monica

1
@fruglemonkey ส่วนแรกของคำตอบของคุณเหมือนกับที่กล่าวมาข้างต้น แต่ก็ยังขอบคุณ ส่วนที่สองฉันไม่คิดว่าจะเหมาะกับฉัน (เว้นแต่ฉันกำลังทำอะไรผิด) ดังนั้นฉันจะต้องไม่ใช้เวอร์ชันที่ถูกต้อง
canwasiereisawelba

5

ฉันคิดว่ามันง่ายที่สุดในการใช้มาโครสำหรับงานที่ต้องยิงครั้งเดียว เพียงเริ่มบันทึกแมโครด้วยqชื่อ + ของการลงทะเบียนและทำงานทันที ฉันเห็นหนึ่งงานที่ทำซ้ำได้ที่นี่:

  • เลือกบรรทัด
  • งัด
  • วาง (จะทำให้คุณอยู่ในบรรทัดถัดไป)
  • ไปที่ท้ายบรรทัด
  • ย้อนกลับไปหนึ่งคำ
  • เพิ่มขึ้นทีละหนึ่ง

ตอนนี้บันทึกการกดแป้นที่ต้องการเพื่อลงทะเบียนaในโหมดปกติ:

qayyp$b<c-a>.

ลบบรรทัดอีกครั้งเพื่อทดสอบว่าการเรียกใช้แมโคร 11 ครั้งให้ผลลัพธ์ที่ถูกต้องกับหนึ่งบรรทัดหรือไม่:

11@a

มันทำ! ดังนั้นให้เลิกทำอีกครั้งและทำให้กระบวนการทั้งหมดเป็นแมโครที่สองโดยอัตโนมัติb:

qb11@aj

ตอนนี้คุณสามารถรัน@bจนกระทั่งสิ้นสุดไฟล์และควรสร้างผลลัพธ์ที่คุณต้องการ มันฟังดูซับซ้อน แต่จริงๆแล้วมันไม่ได้เมื่อคุณคุ้นเคยกับรูปแบบการแก้ไขทั่วไป


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

3
qaVyp$b<c-a>ผมคิดว่าแมโครแรกที่ควรจะ qayyp$b<c-a>หรือดีกว่าเพียงแค่
Karl Yngve Lervåg

1
ขอบคุณ @ KarlYngveLervågคุณพูดถูกฉันซ่อมมาโครแล้ว
kba ย่อมาจาก Monica

2
Argh :( ขอบคุณที่เป็นอย่างละเอียด @ablewasiereisawelba ฉันเดาว่ามาโครqqyyp$?\d<CR><Ctrl-a>qโดย @fruglemonkey และ @jjaderberg นั้นดีกว่าเพราะมันค้นหาหมายเลขสุดท้ายฉันจะเปลี่ยนมันให้สมบูรณ์
kba ย่อมาจาก Monica

2
@kba ฉันแค่คิดว่าถ้าใครใช้เวลาและความพยายามในการตอบคำถามของฉันฉันอย่างน้อยก็สามารถลองแก้ปัญหาของเขา - แม้ว่าฉันได้พบวิธีการทำงานจากคนอื่นแล้ว ฉันซาบซึ้งในความพยายามของคุณ - และถ้ามันทำให้คุณรู้สึกดีขึ้นคุณก็ยังคงอยู่ข้างหน้าฉัน :)
canwasiereisawelba

2

บันทึกแมโครต่อไปนี้และใช้กับแต่ละบรรทัด:

qqyy11p/\/\zs1<CR><C-v>10jg<C-a>q

ข้อแตกต่างที่สำคัญเหนือคำตอบอื่น ๆ คือการใช้ประโยชน์จากg<C-a>การเลือกคอลัมน์ที่เพิ่มแต่ละบรรทัดด้วยจำนวนที่แตกต่างกัน ตรวจสอบ:help v_g_CTRL-Aข้อมูลเพิ่มเติม ฉันเคยใช้\zsเพื่อเลือกตำแหน่งเริ่มต้นของรูปแบบเช่นเคอร์เซอร์จะหยุดที่หมายเลขหลังการค้นหา

โปรดทราบว่าคุณต้องการ Vim เวอร์ชันล่าสุดเพื่อให้สามารถใช้งานได้


1
เสนอ @fruglemonkey ด้วยเช่นกันว่า มันเป็นคุณสมบัติเจ๋ง ๆ แม้ว่ามันจะค่อนข้างเร็ว (ตามมาตรฐานที่เป็นกลุ่ม) ตั้งแต่ 7.4.754 ซึ่งยังไม่ได้ส่งไปยัง distros ทั้งหมด
kba ย่อมาจาก Monica

พลาดไปขอโทษ
Vitor

1
@Vitor ฉันเพิ่งมี gVim 7.4 ดังนั้นฉันไม่คิดว่าฉันสามารถทำg<C-a>@fruglemonkey นั้นได้และคุณก็อ้างถึง แต่ขอบคุณที่ตอบกลับ ฉันควรทราบว่าเมื่อลองใช้แมโครของคุณ - ก่อนที่ฉันจะไปถึงg<C-a>ส่วนนั้นมันไม่ใช่ตัวอักษร "1" ตัวสุดท้ายที่ฉันกำลังมองหาส่วนเพิ่มที่ได้รับการเน้นบล็อก แต่แทนที่จะเป็นตัวละครก่อนหน้า "1 "ตัวละครที่ได้รับการเน้นบล็อก (นอกจากนี้ฉันคิดว่ามันน่าจะเป็นyy11pและ10jในมาโครเนื่องจากฉันต้องการเพิ่ม 11 บรรทัด - รวม 12 บรรทัด)
canwasiereisawelba

1
ขอบคุณสำหรับความคิดเห็นของคุณ ฉันได้อัพเดตคำตอบแล้ว ตัดสินใจที่จะใช้\zsแต่ฉันสามารถก็เช่นกันเพียงแค่ได้เพิ่มหลังl <CR>
Vitor

1
คุณอาจมีการตั้งค่าบางอย่างใน vimrc ของคุณที่มีผลต่อการค้นหานิพจน์ทั่วไป vim -u NONEลองอีกครั้งเริ่มต้นที่เป็นกลุ่มที่มี ฉันเพิ่งทำไปแล้วมันใช้งานได้อย่างสมบูรณ์แบบ! ในความเป็นจริงไม่มีวิธีที่การค้นหาจะตรงกับ 1 รายการแรกเนื่องจากต้องใช้เครื่องหมายทับก่อนหน้า
Vitor
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.