Jawaban:
Perintah Vim's: g dirancang untuk tugas seperti ini; menjalankan satu aksi pada setiap baris yang cocok dengan pola tertentu. Inilah jawaban saya:
:g/.\n\n\@!/norm o
Pola yang saya gunakan adalah /.\n\n\@!/
. Memecah itu menjadi potongan-potongan komponennya:
.
Cocok dengan karakter apa pun di baris. (digunakan untuk segera membuang baris kosong yang ada dari pertimbangan)\n
Cocokkan satu \ n di akhir karakter di atas\n\@!
Gagal mencocokkan jika ada yang lain \ n segera setelah yang sebelumnya \ n.(Periksa :h E59
informasi lebih lanjut tentang \@!
dan specifier pertandingan serupa dalam ekspresi reguler - ada beberapa pasangan lainnya juga!)
Jadi regex perintah: g sekarang telah memilih setiap baris non-kosong yang diakhiri oleh satu baris baru, dan yang tidak diikuti oleh baris kosong.
Setelah pola dalam :g
pernyataan muncul perintah untuk dijalankan pada baris yang cocok. Dalam hal ini, saya telah memerintahkannya untuk menjalankan perintah mode normal (disingkat norm
), dan perintah untuk menjalankannya sederhana o
, yang menyisipkan baris kosong di bawah baris saat ini.
Jadi, secara bersama-sama, perintah menemukan setiap baris yang tidak memiliki baris kosong di bawahnya, dan menambahkan satu. Dan hanya itu yang ada untuk itu! Anda mungkin ingin memeriksa artikel Power of G dari wiki vim untuk hal-hal mewah yang dapat Anda lakukan :g
(dan ini adalah saudara negatif, :v
) - itu adalah salah satu dari perintah yang sangat berguna yang segera akan Anda andalkan, dan kemudian lewatkan sangat dalam editor yang tidak memilikinya.
:%s/$/
, lalu tekan ^V
, lalu tekan Enter
.
:%s/$/<C-V><CR><CR>
(untuk menggunakan pengodean tombol vim-folk yang umum), pendekatan itu hanya menambahkan baris baru setelah setiap baris. Yaitu, baris yang sudah dipisahkan oleh kosong (lihat Baris 3 -> Baris 4, dalam contoh teks) akhirnya mendapatkan baris kosong tambahan. Pertanyaan awal adalah untuk menghindari menambahkan baris kosong tambahan di mana mereka sudah ada di teks awal.
Ketika saya menguji pencarian global dan jawaban pengganti @ NeilForester, saya menemukan bahwa itu melewatkan setiap penggantian yang dimaksudkan setiap detik dalam baris non-kosong berturut-turut jika garis hanya memiliki satu karakter di masing-masing. Ini tampaknya disebabkan oleh pola yang mulai cocok pada setiap kesempatan setelah karakter terakhir yang cocok dengan kesempatan sebelumnya.
Menggunakan lookbehind dan lookahead memecahkan masalah ini dan membuat regex sedikit lebih pendek juga:
:%s/\n\@<!\n\n\@!/\r\r/g
\n\@<!\n
berarti setiap linebreak yang tidak tepat setelah linebreak lain apakah itu benar? Tetapi saya tidak mengerti apa \n\@!
artinya. Saya ingin memahaminya sehingga saya dapat belajar dan menerapkannya pada pola pencarian lain :)
\n\@<!\n
berarti setiap linebreak yang tidak langsung mengikuti linebreak lain. \n\@!
cocok dengan lebar nol jika atom sebelumnya (yaitu \n
) tidak cocok sebelum apa yang terjadi selanjutnya. Coba :help \@<!
lihat dokumentasi tentang ini di vim. I
Cara lain:
%s/\(.\)\n\(.\)/\1\r\r\2/
Yang berarti,
\(.\) match and capture a non-newline character,
\n match a newline
\(.\) match and capture a non-newline character
ganti dengan: tangkapan pertama, gandakan baris baru, dan tangkapan kedua.
Misalnya, line1\nLine2
menghasilkan \1 = 1
dan \2 = L
.
Koreksi saya jika saya salah. Saya percaya Anda menggunakan huruf k ketika dalam mode perintah untuk bergerak ke bawah baris. Kemudian masuk ke mode sisipkan dan tambahkan baris berikutnya. Ulangi seperlunya? Semoga ini membantu!
k
bergerak ke atas garis. j
bergerak ke bawah garis.
/[^\n]\n[^\n]
:map <F2> no<esc><F2>
Lalu tekan <F2>
. Itu akan mencari dua baris non-kosong berturut-turut, dan kemudian menambahkan garis di antara mereka, berulang kali.
Edit:
Berikut cara alternatif untuk melakukannya dengan pencarian global tunggal dan ganti:
:%s/\([^\n]\)\n\([^\n]\)/\1\r\r\2/g
Coba perintah ini ( 16
karakter):
:%!sed G|cat -s
:%norm o
tetapi ternyata ini tidak berfungsi sebagaimana dimaksud dalam kasuso
. +1