Cách thực hiện trong Vim:
TRƯỚC:
aaa
bbb
ccc
ddd
eee
fff
SAU:
aaa
ccc
eee
Cách thực hiện trong Vim:
TRƯỚC:
aaa
bbb
ccc
ddd
eee
fff
SAU:
aaa
ccc
eee
Câu trả lời:
Bạn có thể sử dụng macro cho việc này. Làm như sau.
gg
.qq
.dd
sau.q
.10000@q
Tái bút: Để chuyển sang chế độ lệnh chỉ cần nhấn Escape một vài lần.
:g/^/+d
từ user stackoverflow.com/users/254635/ib (dưới đây) là cách giải quyết vấn đề này một cách thanh lịch hơn.
Một cách thanh lịch (và hiệu quả) để hoàn thành nhiệm vụ là gọi :+delete
lệnh xóa dòng theo sau dòng hiện tại, trên mọi dòng bằng :global
lệnh:
:g/^/+d
:1d|g/^/+d
xóa các dòng lẻ.
Chúng ta có thể sử dụng :normal
hoặc :norm
thực hiện các lệnh chế độ bình thường đã cho. Nguồn.
:%norm jdd
%norm ddj
không hoạt động nếu bạn muốn xóa các hàng lẻ.
:map ^o ddj^o
^o
Đây ^ là viết tắt của CTRL. Macro đệ quy để xóa một dòng sau mỗi hai dòng. Chọn tốt dòng đầu tiên của bạn và nó đã hoàn thành.
từ kho lưu trữ thư vim :
:let i=1 | while i <= line('$') | if (i % 2) | exe i . "delete" | endif | let i += 1 | endwhile
(Được gõ trên một dòng trên dòng lệnh vim, sẽ xóa hàng 1,3,5,7, ...)
!perl -ne 'print unless $. % 2'
:-)
if (expression)
mà cũng hoạt động với mọi dòng thứ ba, v.v.
Bạn luôn có thể chuyển qua lệnh shell, có nghĩa là bạn có thể sử dụng bất kỳ ngôn ngữ kịch bản nào bạn thích:
:%!perl -nle 'print if $. % 2'
(hoặc sử dụng "trừ khi" thay vì "nếu", tùy thuộc vào dòng nào bạn muốn)
-l
chuyển sang Perl ... ngoài ra, tôi muốn nói rằng nó awk
phổ biến hơn Perl một chút, mặc dù nó không thực sự nhiều hơn những ngày này và có thể làm điều này ngắn hơn:, :%!awk NR\%2
hoặc :%!awk 1-NR\%2
đối với các dòng khác.
:%!awk -- '++c\%2'
cách khác
:%!awk -- 'c++\%2'
tùy thuộc vào nửa mà bạn muốn loại bỏ.
NR
biến hiện có ?
:%!awk NR\%2
hoặc :%!awk 1-NR\%2
, như tôi đã đăng trong một bình luận khác. Điều đó hầu như không lâu hơn.
1-NR
dài hơn c++
. Vâng, tôi biết đó là một nhân vật. Như tôi đã nói - lý do thực sự là tôi đã quên mất nó. Dù sao, có vẻ như mọi người không đánh giá cao vẻ đẹp của awk ở đây.
NR
ngắn hơn ++c
:)
Bạn có thể sử dụng các khả năng tìm kiếm và thay thế của chính Vim như sau: Đặt con trỏ của bạn ở dòng đầu tiên và nhập ở chế độ bình thường:
:.,/fff/s/\n.*\(\n.*\)/\1/g
.,/fff/
là phạm vi sử dụng quyền thay người. Nó có nghĩa là "từ dòng này đến dòng khớp với regex fff
(trong trường hợp này là dòng cuối cùng).s///
là lệnh thay thế. Nó tìm kiếm một regex và thay thế mọi lần xuất hiện của nó bằng một chuỗi. Ở g
cuối có nghĩa là lặp lại sự thay thế miễn là regex vẫn được tìm thấy.\n.*\(\n.*\)
khớp với một dòng mới, sau đó .*
khớp với toàn bộ dòng ( khớp với bất kỳ số ký tự nào ngoại trừ một dòng mới), rồi đến một dòng mới và một dòng khác. Dấu ngoặc đơn \(
và \)
ghi lại biểu thức bên trong chúng, vì vậy chúng ta có thể sử dụng nó sau này \1
.\1
chèn dòng mới đã nhóm và dòng sau nó trở lại, bởi vì chúng tôi không muốn dòng tiếp theo cũng biến mất - chúng tôi chỉ muốn cơ chế thay thế đi qua nó để chúng tôi không xóa nó trong lần thay thế tiếp theo.Bằng cách này, bạn có thể kiểm soát phạm vi mà bạn muốn xóa diễn ra và bạn không phải sử dụng bất kỳ công cụ bên ngoài nào.
$
thay vì /fff/
, đối với phần cuối của tệp bất kể nội dung của tệp.
Như một cách tiếp cận khác, bạn cũng có thể sử dụng python nếu vim của bạn có hỗ trợ cho nó.
:py import vim; cb = vim.current.buffer; b = cb[:]; cb[:] = b[::2]
b = cb[:]
sao chép tạm thời tất cả các dòng trong bộ đệm hiện tại sang b
. b[::2]
lấy mỗi dòng thứ hai từ bộ đệm và gán nó cho toàn bộ bộ đệm hiện tại cb[:]
. Bản sao tới b
là cần thiết vì các đối tượng đệm dường như không hỗ trợ cú pháp lát cắt mở rộng.
Đây có lẽ không phải là "vim way", nhưng có thể dễ nhớ hơn nếu bạn biết python.
Để xóa các dòng lẻ (1,3,5, ..) -> :%s/\(.*\)\n\(.*\)\n/\2\r/g
Để xóa các dòng chẵn (2,4,6, ..) -> :%s/\(.*\)\n.*\n/\1\r/g
Tìm kiếm văn bản (tạo dòng đầu tiên) theo sau là một ký tự dòng mới và một số văn bản khác (tạo dòng thứ hai), theo sau là một ký tự dòng mới khác và thay thế ở trên bằng kết hợp đầu tiên (dòng lẻ) hoặc kết hợp thứ hai (dòng chẵn) tiếp theo là ký tự xuống dòng.
bạn có thể thử điều này trong vim
:1,$-1g/^/+1d
Tôi sẽ cố gắng nói rõ hơn (hai phần)
phần đầu tiên phạm vi lựa chọn ( :from,to
)
phần thứ hai hành động ( d
xóa)
:1,$-1
)g
) delete ( +1d
) dòng tiếp theobạn có thể cố gắng di chuyển đến dòng đầu tiên của tệp và thực thi, :+1d
bạn sẽ thấy dòng tiếp theo biến mất
Tôi biết nó là bùn, nhưng đó là khí lực và nó hoạt động