Jak: g /^$/,/./- j (redukuje wiele pustych linii do jednego pustego miejsca) działa w vimie?

21

W artykule Vim Regular Expressions Oleg Raisky podaje następujące polecenie, aby zredukować wiele pustych wierszy do jednego pustego:

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

Czy ktoś może opisać, jak to działa?

Znam :gpolecenia i wyrażenia regularne. Ale nie zrozumiałem, co /,/./-jrobi ta część .

200_sukces
źródło

Odpowiedzi:

24

To naprawdę genialne. Rozbijmy to. exkomenda

g/^$/xyzzy

wyszuka wszystkie puste linie i wykona xyzzypolecenie (dowolne expolecenie) na każdym z nich. Zauważ, że xyzzyto nie jest prawdziwe ex polecenie, jest tylko jako symbol zastępczy, jak w następnym akapicie.

Problem polega na tym, że xyzzy„polecenie” w twoim przypadku jest kolejnym poleceniem wyszukiwania:

,/./-j

,/./-Określa zakres. Ma to postać <start>,<end>i ponieważ przecinek nie ma nic, zakłada, że ​​bieżąca linia (ta, w której znalazłeś pustą linię) jest początkiem.

Po przecinku /./-oznacza poszukiwanie następnego znaku ( .oznacza dowolny znak), a następnie cofnij się o jedną linię ( /./-jest to skrót, /./-1ponieważ sugeruje się, że jeśli nie podano żadnej wartości). Ten wzór znajdziesz .w pierwszym niepustym wierszu następującym po tym, na którym operujesz.

Innymi słowy, koniec zakresu jest ostatnim pustym wierszem za lub w tym, w którym aktualnie pracujesz.

Następnie wykonujesz sprzężenie w tym zakresie.

Jeśli początek i koniec zakresu były równe (w sekcji była tylko jedna pusta linia), łączenie nic nie robi. Jeśli nie są równe, dołącz dołączy do nich wszystkich.

W ten sposób łączy wiele pustych linii w jedną.

Spójrzmy na przykład (numery wierszy służą jedynie wyjaśnieniu, nie ma ich w rzeczywistym pliku):

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

g/^$/Polecenie znajdzie wszystkie pustych wierszy i wykonywać swoje działanie na nich (są to linie 2, 5, 6, 7 i 8).

Dla linii 2 ,/./-justawi zakres od 2 do 2 (następny .znajduje się w linii 3, a następnie odejmij 1, aby uzyskać 2). Łączenie w zakresie 2,2 nic nie robi.

W wierszu 5 ,/./-justawi zakres od 5 do 8 (następny .w wierszu 9, a następnie odejmij 1). Łączenie w zakresie 5,8 połączy wszystkie te linie razem.

Operacja nie jest wykonywana na liniach, które znikają w ramach wcześniejszej operacji. Jest tak, ponieważ nie ma sensu przetwarzać linii, które zostały usunięte wcześniej w cyklu.

Innymi słowy, ponieważ wiersze od 6 do 8 są usuwane (w połączeniu z wierszem 5), polecenie globalne po nich nie działa.

Opiera się to na tym, że vimdokumentacja zawiera algorytm dwuprzebiegowy, jeden do oznaczania linii, drugi do wykonywania operacji.


źródło
2
Pamiętaj, że to polecenie narzeka, jeśli na końcu pliku są puste linie.
Wildcard,