Bagaimana cara: g /^$/,/./- j (mengurangi beberapa baris kosong menjadi satu kosong) berfungsi dalam vim?

21

Dalam artikel tersebut, Vim Regular Expressions , Oleg Raisky memberikan perintah berikut untuk mengurangi beberapa baris kosong menjadi satu baris kosong:

:g/^$/,/./-j

Bisakah seseorang tolong jelaskan bagaimana ini bekerja?

Saya tahu :gperintah dan ekspresi reguler. Tetapi saya tidak mengerti apa yang dilakukan bagian /,/./-jitu.

200_sukses
sumber

Jawaban:

24

Benar-benar sangat cerdik. Mari kita jabarkan. The experintah

g/^$/xyzzy

akan mencari semua baris kosong dan menjalankan xyzzyperintah ( experintah arbitrer ) pada masing-masing. Perhatikan bahwa xyzzyini bukan perintah sebenarnya ex , itu hanya ada sebagai pengganti, sesuai paragraf berikutnya.

Agak sulit di sini adalah bahwa xyzzy"perintah" dalam kasus Anda adalah perintah pencarian lain :

,/./-j

The ,/./-menentukan kisaran. Ini adalah bentuk <start>,<end>dan, karena tidak ada sebelum koma, itu mengasumsikan baris saat ini (yang mana Anda menemukan baris kosong) adalah awal.

Setelah koma /./-yang berarti mencari karakter berikutnya ( .berarti karakter apa saja) kemudian buat cadangan satu baris ( /./-kependekan /./-1karena yang tersirat jika tidak ada nilai yang diberikan). Anda akan menemukan pola itu .di baris non-kosong pertama setelah yang Anda operasikan.

Dengan kata lain, akhir rentang adalah baris kosong terakhir setelah atau pada baris yang sedang Anda operasikan.

Kemudian Anda menjalankan gabungan pada rentang itu.

Jika awal dan akhir rentang sama (hanya satu baris kosong di bagian), bergabung tidak melakukan apa pun. Jika mereka tidak sama, bergabunglah dengan mereka semua.

Begitulah cara menggabungkan beberapa baris kosong menjadi satu.

Mari kita lihat sebuah contoh (nomor baris hanya untuk penjelasan, mereka tidak ada dalam file yang sebenarnya):

1 Line 1
2
3 Line 3
4 Line 4
5
6
7
8
9 Line 9

The g/^$/perintah akan menemukan semua baris kosong dan melakukan operasi pada mereka (ini adalah garis 2, 5, 6, 7 dan 8).

Untuk baris 2, ,/./-jakan menyiapkan rentang 2 hingga 2 (berikutnya .ditemukan pada baris 3 lalu kurangi 1 untuk mendapatkan 2). Bergabung di kisaran 2,2 tidak melakukan apa-apa.

Untuk saluran 5, ,/./-jakan menyiapkan rentang dari 5 hingga 8 (selanjutnya .ditemukan pada baris 9 lalu kurangi 1). Bergabung di kisaran 5,8 akan menggabungkan semua garis itu bersama-sama.

Operasi tidak dilakukan pada garis yang hilang sebagai bagian dari operasi sebelumnya. Itu karena tidak masuk akal untuk memproses baris yang telah dihapus sebelumnya dalam siklus.

Dengan kata lain, karena baris 6 hingga 8 dihapus (digabungkan dengan baris 5), perintah global tidak beroperasi setelahnya.

Itu didasarkan pada kenyataan bahwa vimdokumentasi menyatakan algoritma dua-pass, satu untuk menandai garis, satu untuk melakukan operasi.


sumber
2
Perhatikan bahwa perintah ini akan mengeluh jika Anda memiliki baris kosong di akhir file Anda.
Wildcard