To naprawdę genialne. Rozbijmy to. ex
komenda
g/^$/xyzzy
wyszuka wszystkie puste linie i wykona xyzzy
polecenie (dowolne ex
polecenie) na każdym z nich. Zauważ, że xyzzy
to 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, /./-1
ponieważ 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 ,/./-j
ustawi 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 ,/./-j
ustawi 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 vim
dokumentacja zawiera algorytm dwuprzebiegowy, jeden do oznaczania linii, drugi do wykonywania operacji.