Vim - Menambahkan baris kosong di antara baris

15

Bagaimana cara saya memasukkan garis kosong di antara setiap baris yang tidak kosong?

misalnya. dari

line 1
line 2
line 3

line 4
line 5

untuk

line 1

line 2

line 3

line 4

line 5
ayutheos
sumber

Jawaban:

27

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 E59informasi 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 :gpernyataan 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.

Trevor Powell
sumber
1
Tepat. Saya biasanya mencari singkatan seperti :%norm otetapi ternyata ini tidak berfungsi sebagaimana dimaksud dalam kasus o. +1
sehe
Ketik :%s/$/, lalu tekan ^V, lalu tekan Enter.
jpaugh
1
@ jpaugh Dengan asumsi maksud Anda :%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.
Trevor Powell
3

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
Simon
sumber
Terima kasih! Ini berfungsi, dan itu tidak menambahkan lebih banyak baris jika saya menjalankan pencarian lagi (jika katakan, saya menambahkan baris baru ke file saya).
1
Bisakah Anda menjelaskan arti setiap regex dalam pola pencarian? Melihat bantuan vim, \n\@<!\nberarti 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 :)
Ya, \n\@<!\nberarti 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
Simon
3

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\nLine2menghasilkan \1 = 1dan \2 = L.

perreal
sumber
0

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!

Nick Gerrer
sumber
kbergerak ke atas garis. jbergerak ke bawah garis.
Neil Forrester
Ya, memang benar. Kesalahanku. Neil terima kasih!
0
/[^\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
Neil Forrester
sumber
File saya memiliki banyak baris. Apakah ada cara untuk melakukan pencarian regex & menyisipkan baris kosong untuk seluruh file? Saya telah mencari di stackoverflow.com/questions/2673209/... tapi tidak bisa memahami apa semua perintah regex berarti.
Lihat hasil edit saya di atas untuk cara alternatif mencapai hal yang sama dalam satu perintah, dan tanpa pemetaan rekursif. Cara pertama seharusnya bekerja untuk seluruh file.
Neil Forrester
0

Coba perintah ini ( 16karakter):

:%!sed G|cat -s
kev
sumber
Alih-alih mencoba untuk "vimgolf" perintah pendek, sedikit penjelasan tentang opsi yang agak tidak jelas yang digunakan akan lebih bermanfaat.
Ingo Karkat
0

Saya tidak tahu berapa lama file Anda, tetapi salah satu metode paling sederhana adalah mengetikkan omode perintah. Dan di baris berikutnya .. Ini bisa dimuat ke makro sederhana.

Demagog
sumber