Vim - Thêm dòng trống giữa các dòng


15

Làm cách nào để tôi chèn một dòng trống giữa mỗi dòng không trống?

ví dụ. từ

line 1
line 2
line 3

line 4
line 5

đến

line 1

line 2

line 3

line 4

line 5

Câu trả lời:


27

Lệnh gim của Vim được thiết kế cho chính xác loại nhiệm vụ này; chạy một hành động duy nhất trên mỗi dòng phù hợp với một mẫu cụ thể. Đây là câu trả lời của tôi:

:g/.\n\n\@!/norm o

Mẫu tôi sử dụng là /.\n\n\@!/. Chia nó thành các phần thành phần của nó:

  • .Phù hợp với bất kỳ nhân vật trong dòng. (được sử dụng để loại bỏ ngay lập tức mọi dòng trống hiện có khỏi xem xét)
  • \n Khớp một \ n ở cuối ký tự ở trên
  • \n\@! Thất bại trận đấu nếu có một \ n khác ngay sau \ n trước đó.

(Kiểm tra :h E59để biết thêm thông tin về\@! và các công cụ xác định đối sánh tương tự trong các biểu thức thông thường - cũng có một vài cái khác!)

Vì vậy, regex của lệnh g hiện đã chọn mọi dòng không trống được kết thúc bởi một dòng mới và không theo sau bởi một dòng trống.

Sau khi mẫu trong một :gcâu lệnh xuất hiện lệnh để chạy trên các dòng khớp. Trong trường hợp này, tôi đã bảo nó thực thi lệnh chế độ bình thường (viết tắt là norm) và lệnh để chạy đơn giản o, nó chèn một dòng trống bên dưới dòng hiện tại.

Vì vậy, được thực hiện cùng nhau, lệnh tìm thấy mọi dòng không có một dòng trống bên dưới nó và thêm một dòng. Và đó là tất cả để có nó! Bạn có thể muốn kiểm tra bài viết Power of G của vim wiki để biết những điều thú vị hơn bạn có thể làm với :g(và đó là chị em tiêu cực :v) - đó là một trong những lệnh hữu ích đáng kinh ngạc mà bạn sớm phát triển để dựa vào, và sau đó bỏ lỡ rất nhiều trong các biên tập viên Mà không có nó.


1
Đúng. Tôi thường tìm kiếm các tốc ký như thế :%norm onhưng hóa ra điều này không hoạt động như dự định trong trường hợp o. +1
sehe

:%s/$/, rồi đánh ^V, rồi đánh Enter.
jpaugh

1
@jpaugh Giả sử rằng bạn có nghĩa là :%s/$/<C-V><CR><CR>(để sử dụng mã hóa vim-dân gian phổ biến của các phím bấm), cách tiếp cận đó chỉ thêm một dòng mới sau mỗi dòng. Đó là, các dòng đã được phân tách bằng khoảng trắng (xem Dòng 3 -> Dòng 4, trong văn bản ví dụ) kết thúc để có thêm các dòng trống. Câu hỏi ban đầu là để tránh thêm các dòng trống bổ sung nơi chúng đã tồn tại trong văn bản bắt đầu.
Trevor Powell

3

Khi tôi kiểm tra câu trả lời tìm kiếm và thay thế toàn cầu của @ NeilForester, tôi thấy rằng nó đã bỏ lỡ mỗi giây thay thế dự định trong các dòng không trống liên tiếp nếu mỗi dòng chỉ có một ký tự. Điều này dường như là do mô hình bắt đầu khớp với mỗi lần sau ký tự cuối cùng mà nó khớp với lần trước.

Sử dụng lookbehind và lookahead sẽ giải quyết vấn đề này và làm cho regex ngắn hơn một chút:

:%s/\n\@<!\n\n\@!/\r\r/g

Cảm ơn! Điều này hoạt động và nó không thêm nhiều dòng nếu tôi chạy lại tìm kiếm (nếu nói, tôi đã thêm các dòng mới vào tệp của mình).

1
Bạn có thể giải thích từng regex trong mẫu tìm kiếm nghĩa là gì không? Nhìn vào trợ giúp của vim, \n\@<!\ncó nghĩa là bất kỳ ngắt dòng nào không đúng sau khi ngắt dòng khác là đúng? Nhưng tôi không thể hiểu ý \n\@!nghĩa của nó. Tôi muốn hiểu nó để tôi có thể tìm hiểu và áp dụng nó cho các mẫu tìm kiếm khác :)

Có, \n\@<!\ncó nghĩa là bất kỳ ngắt dòng nào không ngay lập tức theo sau một ngắt dòng khác. \n\@!khớp với độ rộng bằng không nếu nguyên tử trước (tức là \n) không khớp ngay trước những gì tiếp theo. Hãy thử :help \@<!xem tài liệu về điều này trong vim. Tôi
Simon

3

Cách khác:

%s/\(.\)\n\(.\)/\1\r\r\2/

Nghĩa là,

\(.\) match and capture a non-newline character,
\n    match a newline
\(.\) match and capture a non-newline character

thay thế bằng: chụp đầu tiên, tăng gấp đôi dòng mới và chụp thứ hai.

Ví dụ, line1\nLine2kết quả trong \1 = 1\2 = L.


0

Đúng nếu tôi đã sai lầm. Tôi tin rằng bạn sử dụng chữ k khi ở chế độ lệnh để di chuyển xuống một dòng. Sau đó vào chế độ chèn và thêm dòng tiếp theo. Lặp lại khi cần thiết? Hi vọng điêu nay co ich!


kdi chuyển lên một dòng. jdi chuyển xuống một dòng.
Neil Forrester

Vâng, thực sự nó làm. Lỗi của tôi. Cảm ơn Neil!

0
/[^\n]\n[^\n]
:map <F2> no<esc><F2>

Sau đó nhấn <F2>. Điều đó sẽ tìm kiếm hai dòng không trống liên tiếp, và sau đó thêm một dòng giữa chúng, lặp đi lặp lại.

Biên tập:

Đây là một cách khác để làm điều đó với một tìm kiếm và thay thế toàn cầu duy nhất:

:%s/\([^\n]\)\n\([^\n]\)/\1\r\r\2/g

Tập tin của tôi có rất nhiều dòng. Có cách nào để thực hiện tìm kiếm regex & chèn dòng trống cho toàn bộ tệp không? Tôi đã xem stackoverflow.com/questions/2673209/ Cách nhưng không thể hiểu tất cả các lệnh regex có nghĩa là gì.

Xem chỉnh sửa ở trên của tôi để biết một cách khác để thực hiện điều tương tự trong một lệnh duy nhất và không có ánh xạ đệ quy. Cách đầu tiên phải làm việc cho toàn bộ tập tin mặc dù.
Neil Forrester

0

Hãy thử lệnh này ( 16ký tự):

:%!sed G|cat -s

Thay vì cố gắng "vimgolf" một lệnh ngắn, một lời giải thích nhỏ về các tùy chọn khá mơ hồ được sử dụng sẽ hữu ích hơn.
Ingo Karkat

0

Tôi không biết tệp của bạn dài bao nhiêu nhưng một trong những phương pháp đơn giản nhất là nhập ochế độ lệnh. Và trong dòng tiếp theo .. Điều này có thể được tải vào macro đơn giản.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.