Saya ingin menyatukan garis hanya untuk garis yang memiliki pola tertentu (seperti ;
), namun ketika menggunakannya g/;/j
tidak berfungsi seperti yang diharapkan kecuali dipanggil beberapa kali.
Misalnya konten berikut:
a
1;
2;
3;
4;
5;
b
6;
7;
8;
9;
c
saat menggunakan: :g/;/j
outputnya adalah:
a
1; 2;
3; 4;
5; b
6; 7;
8; 9;
c
atau :g/;/-j
memberi:
a 1; 2; 3; 4; 5;
b 6; 7; 8; 9;
c
sama dengan: :g/;\_.\{-};/j
.
Output yang saya harapkan adalah:
a
1; 2; 3; 4; 5;
b
6; 7; 8; 9;
c
atau yang serupa, jadi semua garis yang mengandung pola digabungkan bersama.
Bagaimana ini bisa dicapai?
global-command
kenorb
sumber
sumber
:g/;/j
tidak berfungsi karena dilakukan dalam dua lintasan: pertama buffer dipindai, kemudian perintah diterapkan ke baris yang cocok.Jawaban:
Kemungkinan penjelasan masalah
Saya pikir alasan mengapa
:g/;/j
tidak bekerja adalah karena:g
perintah beroperasi dengan algoritma 2-pass:;
Selama lintasan kedua,
:g
gabungkan garis1;
dengan garis2;
karena1;
ditandai selama lintasan pertama. Namun saya curiga (tidak yakin) bahwa itu tidak bergabung1; 2;
dengan3;
karena garis2;
tidak ada lagi, isinya telah digabung dengan garis1;
yang telah diproses.Jadi
:g
cari baris berikutnya yang ditandai saat pass pertama (3;
) dan gabung dengan yang berikutnya (4;
). Setelah itu masalah berulang, itu tidak bisa bergabung3; 4;
dengan5;
karena garis4;
tidak ada lagi.Solusi 1 (dengan vimscript)
Mungkin Anda bisa memanggil fungsi kapan pun baris yang
;
ditemukan ditemukan untuk memeriksa apakah baris sebelumnya juga mengandung tanda titik koma:Kemudian gunakan perintah global berikut:
Atau tanpa fungsi:
Solusi 2 (tanpa skrip)
Setiap kali perintah global
:g
menemukan pola;
itu menjalankan perintah:.,/^[^;]*$/-1j
Itu bisa dipecah seperti ini:
Dimana:
b
dapat dirinci lebih lanjut seperti ini:j
adalah bentuk disingkat dari perintah Ex:join
yang seperti kebanyakan perintah Ex lainnya dapat didahului oleh suatu range.Di sini diawali oleh rentang:
.,/^[^;]*$/-1
(a,b
)Suatu rentang mengikuti bentuk di
a,b
manaa
danb
biasanya 2 nomor garis, dan memungkinkan Anda untuk beroperasi pada sekelompok garis yang jumlahnya antaraa
danb
, bukan hanya satu.Jadi
j
perintah bergabung dengan semua baris antara yang sekarang (a
) dan yang berikutnya yang tidak mengandung titik koma minus satu (b
).Untuk informasi lebih lanjut, lihat:
sumber
Saya melakukan hal serupa saat bergabung dengan pencarian global dan ganti:
\n
cocok dengan baris baru.Untuk menemukan dan menghapus baris kosong:
Saya tidak yakin mengapa, tetapi jika ingin memasukkan baris baru yang harus Anda gunakan
\r
sumber
s
sendiri akan bekerja hanya untuk satu baris, untuk menjadikannya global, Anda perlu menggunakan%s
, tetapi kemudian ia akan bergabung dengan hampir semua baris, termasuk non-;
baris:s
perintah tepat untuk apa yang Anda inginkan. Saya pikir ini%s/;\n\(.*;\)\@=/;/
melakukan apa yang Anda butuhkan.