Sed regex'i vim regex'e dönüştürme
Bulduğum bu eski normal ifadeyi aldım:
sed '/start/!d;s//&\n/;s/.*\n//;:a;/end/bb;$!{n;ba};:b;s//\n&/;P;D'
temelde bir başlangıç noktası ile bir bitiş noktası arasındaki içeriği çıkarır.
##1##
this is a test
with multiple
line
##z##
ve değiştirme startile ##1##ve endhiç ##z##verecekti:
this is a test
with multiple
line
Birden fazla kopyasını varsa ##1##ve ##z##o zaman tabii ki gösterecek aradaki tüm söyleyen bir oluşum, şöyle metni:
##1##
this is a test
with multiple
line
##z##
##1##
this is a test
with multiple
line
##z##
-e
this is a test
with multiple
line
this is a test
with multiple
line
Daha da netleştirmek için:
##1##
this is a test
with multiple
line
##z##
##2##
test
##z##
açıkça sadece başlangıç noktası olarak belirtilenleri verir (çünkü bitiş noktası ##z##her zaman aynıdır). Yani ##2##bunun yerine başlangıç noktası olarak kullanırsam :
test
Bu, yukarıdakileri çıktı olarak verir.
Amacım bunu vim için uyumlu bir regex'e dönüştürmektir. Ben kullanıyorum bu siteyi nereye vim regex için yukarıdaki dönüştürmek için başlamak için ben emin değilim ve yardım gibi yerel kılavuzu ama.
Yanıtlar
İşi çok daha deyimsel olarak yapan son derece basit bir işlev:
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
Ne istersen adlandır ve sonra yap, örneğin,
call Between('##1##', '##z##')
(belki de bir anahtara bağlayabilirsiniz).
Bütün dosya üzerinde çalışması için, belki kullanabilmek için :global(hatta sadece :%call Between(...)) veya bir döngü bu işlevi sarma ve dosyayı kateden gerekebilir. İkincisi durumunda search(a:start), bir sonraki başlangıcı bulmak ve sonra +iç içe geçmiş bölgenin içinde olmak için kullanırım; o zaman işlevi çağırırdım. Bu, işlevi her satırda çağırmaktan daha hızlıdır.
:g/END\|\%^/,/START\|\%$/s/.*//
Bu global komut, eşleşen tüm satırları ENDveya dosyanın ( \%^) başlangıcını işaretler . Ardından , ikame komutunu kullanarak işaretli satırlardan STARTdosyanın sonuna ( \%$) kadar veya sonuna kadar olan her şeyi silmeye devam eder s/.*//.
Yan yana bir örnek:
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 |
Eğer boş satırlar istemiyorsanız, o kadar değiştirebileceğiniz s/.*//tarafından dküresel komuta.
Sadece eğlence için, her zaman yapabileceğini unutma
:%!sed '/start/\!d;s//&\n/;s/.*\n//;:a;/end/bb;$\!{n;ba};:b;s//\n&/;P;D'
Ve bu hala "vim": P