ฉันต้องการลบบรรทัดอื่น ๆ ทั้งหมดออกจาก Vim buffer โดยเริ่มจากบรรทัดที่สองเช่นบรรทัดที่ 2, 4, 6 เป็นต้นตัวอย่างเช่นหากเนื้อหาของบัฟเฟอร์คือ:
aaa
bbb
ccc
ddd
eee
fff
จากนั้นหลังจากลบบรรทัดที่ต้องการแล้วควรกลายเป็น:
aaa
ccc
eee
ฉันต้องการลบบรรทัดอื่น ๆ ทั้งหมดออกจาก Vim buffer โดยเริ่มจากบรรทัดที่สองเช่นบรรทัดที่ 2, 4, 6 เป็นต้นตัวอย่างเช่นหากเนื้อหาของบัฟเฟอร์คือ:
aaa
bbb
ccc
ddd
eee
fff
จากนั้นหลังจากลบบรรทัดที่ต้องการแล้วควรกลายเป็น:
aaa
ccc
eee
คำตอบ:
คุณสามารถใช้มาโครสำหรับสิ่งนี้ ดำเนินการดังต่อไปนี้
gg
ไปที่จุดเริ่มต้นของไฟล์โดยการกดqq
กดdd
หลังq
กด10000@q
PS: หากต้องการไปที่โหมดคำสั่งเพียงแค่กด Escape สองสามครั้ง
:g/^/+d
จากผู้ใช้stackoverflow.com/users/254635/ib (ร้อง) เป็นวิธีที่ดีกว่าในการแก้ปัญหานี้
วิธีที่สง่างาม (และมีประสิทธิภาพ) ในการทำงานให้สำเร็จคือการเรียกใช้:+delete
คำสั่งลบบรรทัดตามบรรทัดปัจจุบันในทุกบรรทัดโดยใช้:global
คำสั่ง:
:g/^/+d
:1d|g/^/+d
ลบเส้นคี่
เราสามารถใช้:normal
หรือ:norm
ดำเนินการตามคำสั่งโหมดปกติที่กำหนด ที่มา
:%norm jdd
%norm ddj
ไม่ทำงานถ้าคุณต้องการลบแถวคี่
:map ^o ddj^o
^o
นี่ ^ ย่อมาจาก CTRL มาโครแบบเรียกซ้ำเพื่อลบบรรทัดทุกๆสองบรรทัด เลือกบรรทัดแรกของคุณให้ดีและเสร็จสิ้น
:let i=1 | while i <= line('$') | if (i % 2) | exe i . "delete" | endif | let i += 1 | endwhile
(หากต้องการพิมพ์ในบรรทัดเดียวบนบรรทัดคำสั่งกลุ่มจะลบแถวที่ 1,3,5,7, ... )
!perl -ne 'print unless $. % 2'
:-)
if (expression)
ซึ่งใช้ได้กับทุกบรรทัดที่สามเป็นต้น
คุณสามารถไพพ์คำสั่งเชลล์ได้ตลอดเวลาซึ่งหมายความว่าคุณสามารถใช้ภาษาสคริปต์ใดก็ได้ที่คุณต้องการ:
:%!perl -nle 'print if $. % 2'
(หรือใช้ "เว้นแต่" แทน "if" ขึ้นอยู่กับบรรทัดที่คุณต้องการ)
-l
เปลี่ยนไปใช้ Perl ... นอกจากนี้ฉันจะบอกว่าawk
มันแพร่หลายกว่า Perl เล็กน้อยแม้ว่าในปัจจุบันจะไม่มากนักและสามารถทำได้สั้นกว่านี้: :%!awk NR\%2
หรือ:%!awk 1-NR\%2
สำหรับบรรทัดอื่น ๆ
:%!awk -- '++c\%2'
หรือ
:%!awk -- 'c++\%2'
ขึ้นอยู่กับว่าคุณต้องการกำจัดวัชพืชออกไปครึ่งหนึ่ง
NR
ตัวแปรที่มีอยู่ล่ะ
:%!awk NR\%2
หรือ:%!awk 1-NR\%2
ตามที่ฉันโพสต์ในความคิดเห็นอื่น แทบจะไม่นาน
1-NR
c++
มีความยาวมากกว่า ใช่ฉันรู้ว่ามันเป็นตัวละครเดียว อย่างที่ฉันพูด - เหตุผลที่แท้จริงคือฉันลืมมันไป อย่างไรก็ตามดูเหมือนว่าผู้คนจะไม่ชื่นชมความงามของ awk ที่นี่
NR
สั้นกว่า++c
:)
คุณสามารถใช้ความสามารถในการค้นหาและทดแทนของ Vim ได้ดังนี้: วางเคอร์เซอร์ไว้ที่บรรทัดแรกแล้วพิมพ์ในโหมดปกติ:
:.,/fff/s/\n.*\(\n.*\)/\1/g
.,/fff/
เป็นช่วงสำหรับการทดแทน หมายความว่า "จากบรรทัดนี้ไปยังบรรทัดที่ตรงกับ regex fff
(ในกรณีนี้คือบรรทัดสุดท้าย)s///
คือคำสั่งแทนที่ ค้นหา regex และแทนที่ทุกครั้งที่เกิดขึ้นด้วยสตริง g
ที่หมายถึงการสิ้นสุดการทำซ้ำเปลี่ยนตัวตราบเท่าที่ regex ทำให้ถูกพบ\n.*\(\n.*\)
จับคู่ขึ้นบรรทัดใหม่จากนั้นทั้งบรรทัด ( .*
จับคู่อักขระจำนวนเท่าใดก็ได้ยกเว้นขึ้นบรรทัดใหม่) จากนั้นขึ้นบรรทัดใหม่อีกบรรทัดและอีกบรรทัด วงเล็บ\(
และก่อให้เกิดการแสดงออกภายในพวกเขาจะได้รับการบันทึกไว้เพื่อให้เราสามารถใช้งานได้ในภายหลังโดยใช้\)
\1
\1
แทรกบรรทัดใหม่ที่จัดกลุ่มและบรรทัดหลังกลับเพราะเราไม่ต้องการให้บรรทัดถัดไปหายไปเราแค่ต้องการให้กลไกการแทนที่ผ่านไปดังนั้นเราจะไม่ลบมันในการแทนที่ครั้งถัดไปด้วยวิธีนี้คุณสามารถควบคุมช่วงที่คุณต้องการให้การลบเกิดขึ้นและคุณไม่ต้องใช้เครื่องมือภายนอกใด ๆ
$
แทนที่จะ/fff/
เป็น end-of-file โดยไม่คำนึงถึงเนื้อหาของไฟล์
อีกวิธีหนึ่งคุณสามารถใช้ python ได้หาก vim ของคุณรองรับ
:py import vim; cb = vim.current.buffer; b = cb[:]; cb[:] = b[::2]
b = cb[:]
b
สำเนาทุกบรรทัดในบัฟเฟอร์ปัจจุบันชั่วคราว ได้รับทุกบรรทัดที่สองจากกันชนและกำหนดให้บัฟเฟอร์ปัจจุบันทั้งหมดb[::2]
cb[:]
การคัดลอกb
เป็นสิ่งที่จำเป็นเนื่องจากวัตถุบัฟเฟอร์ดูเหมือนจะไม่รองรับไวยากรณ์ของสไลซ์ที่ขยายออกไป
นี่อาจไม่ใช่ "vim way" แต่อาจจำได้ง่ายกว่าถ้าคุณรู้จัก python
ในการลบเส้นคี่ (1,3,5, .. ) -> :%s/\(.*\)\n\(.*\)\n/\2\r/g
ในการลบเส้นคู่ (2,4,6, .. ) -> :%s/\(.*\)\n.*\n/\1\r/g
ค้นหาข้อความ (สร้างบรรทัดแรก) ตามด้วยอักขระบรรทัดใหม่และข้อความเพิ่มเติมบางส่วน (สร้างบรรทัดที่สอง) ตามด้วยอักขระบรรทัดใหม่อื่นและแทนที่ด้านบนด้วยการจับคู่แรก (บรรทัดคี่) หรือการจับคู่ที่สอง (เส้นคู่) ตามด้วยการคืนรถ
เรียก sed:
:% !sed -e '2~2 d'
^^^^ pipe file through a shell command
^^^^^^ the command is sed, and -e describes an expression as parameter
^^^^^ starting with the second line, delete every second line
คุณสามารถลองสิ่งนี้ในกลุ่ม
:1,$-1g/^/+1d
ฉันจะพยายามให้ชัดเจนมากขึ้น (สองส่วน)
ส่วนแรกช่วงการเลือก ( :from,to
)
ส่วนที่สองการกระทำ ( d
ลบ)
:1,$-1
)g
) ลบ ( +1d
) บรรทัดถัดไปคุณสามารถลองย้ายไปที่บรรทัดแรกของไฟล์และดำเนินการ:+1d
คุณจะเห็นว่าบรรทัดถัดไปหายไป
ฉันรู้ว่ามันเป็นโคลน แต่มันก็เป็นกลุ่มและใช้งานได้