Ubah sed regex ke vim regex
Saya mendapatkan sed regex ini yang saya temukan:
sed '/start/!d;s//&\n/;s/.*\n//;:a;/end/bb;$!{n;ba};:b;s//\n&/;P;D'
yang pada dasarnya mengeluarkan konten yang berada di antara titik awal dan titik akhir.
##1##
this is a test
with multiple
line
##z##
dan mengganti startdengan ##1##, dan enduntuk ##z##akan memberikan:
this is a test
with multiple
line
Jika ada beberapa kemunculan dari ##1##dan ##z##, maka itu jelas akan menampilkan semua teks di antara kejadian tersebut, seperti:
##1##
this is a test
with multiple
line
##z##
##1##
this is a test
with multiple
line
##z##
untuk
this is a test
with multiple
line
this is a test
with multiple
line
Untuk memperjelas lebih lanjut:
##1##
this is a test
with multiple
line
##z##
##2##
test
##z##
jelas hanya akan memberikan apa yang ditentukan sebagai titik awal (karena titik akhir ##z##selalu sama). Jadi jika saya menggunakan ##2##sebagai titik awal:
test
Ini akan memberikan yang di atas sebagai output.
Tujuan saya adalah untuk mengubahnya menjadi regex yang kompatibel untuk vim. Saya menggunakan situs ini dan panduan lokal sebagai bantuan, tetapi saya tidak yakin harus mulai dari mana untuk mengonversi yang di atas ke vim regex.
Jawaban
Fungsi yang sangat sederhana yang melakukan pekerjaan dengan lebih idiomatis:
function! Between(start, end) abort
let [start_line, _] = searchpairpos(a:start, '', a:end, 'bWn')
let [end_line, _] = searchpairpos(a:start, '', a:end, 'Wn')
if start_line is# 0 || end_line is# 0
return
endif
call setline(start_line, '') " or: execute start_line 'delete'
call setline(end_line, '') " or: execute end_line 'delete'
endfunction
Beri nama apa pun yang Anda inginkan, lalu lakukan, misalnya,
call Between('##1##', '##z##')
(yang bisa Anda ikat ke sebuah kunci, mungkin).
Untuk mengerjakan seluruh file, Anda mungkin dapat menggunakan :global(atau bahkan hanya :%call Between(...)), atau Anda mungkin memerlukan loop yang membungkus fungsi ini dan melintasi file. Dalam kasus yang terakhir, saya akan menggunakan search(a:start)untuk menemukan awal berikutnya dan kemudian +berada di dalam wilayah bersarang; maka saya akan memanggil fungsinya. Ini lebih cepat daripada memanggil fungsi di setiap baris.
:g/END\|\%^/,/START\|\%$/s/.*//
Perintah global ini menandai semua baris yang cocok ENDatau awal file ( \%^). Kemudian ia melanjutkan untuk menghapus semuanya mulai dari baris yang ditandai hingga STARTatau akhir file ( \%$) dengan menggunakan perintah substitusi s/.*//.
Contoh berdampingan:
Before |After
________________________________
test |
START |
this is a test |this is a test
with multiple |with multiple
line |line
END |
0 |
START |
0101 |0101
END |
11 |
111 |
Jika Anda tidak menginginkan baris kosong, Anda bisa mengganti s/.*//dengan ddi perintah global.
Hanya untuk bersenang-senang, ingatlah Anda selalu bisa melakukannya
:%!sed '/start/\!d;s//&\n/;s/.*\n//;:a;/end/bb;$\!{n;ba};:b;s//\n&/;P;D'
Dan itu masih “vim”: P