Vim - Dodawanie pustej linii między liniami


15

Jak wstawić pustą linię między każdą niepustą linią?

na przykład. od

line 1
line 2
line 3

line 4
line 5

do

line 1

line 2

line 3

line 4

line 5

Odpowiedzi:


27

Polecenie Vima: g jest przeznaczone właśnie do tego rodzaju zadań; uruchomienie pojedynczej akcji na każdej linii, która pasuje do określonego wzorca. Oto moja odpowiedź:

:g/.\n\n\@!/norm o

Wzór, którego używam to /.\n\n\@!/. Podział na części składowe:

  • .Dopasowuje dowolny znak w linii. (służy do natychmiastowego odrzucenia wszelkich istniejących pustych linii z analizy)
  • \n Odpowiada pojedynczemu \ n na końcu powyższego znaku
  • \n\@! Nie powiedzie się, jeśli jest inny \ n zaraz po wcześniejszym \ n.

(Sprawdź :h E59więcej informacji o \@!podobnych specyfikacjach dopasowania w wyrażeniach regularnych - jest też kilka innych!)

Zatem wyrażenie regularne polecenia: g wybrało teraz każdą niepustą linię, która kończy się pojedynczą nową linią, a po której nie następuje pusta linia.

Po wzorcu w :ginstrukcji pojawia się polecenie uruchomienia na pasujących liniach. W tym przypadku kazałem mu wykonać polecenie w trybie normalnym (w skrócie norm), a polecenie do uruchomienia jest po prostu o, które wstawia pustą linię poniżej bieżącej linii.

Podsumowując, polecenie znajduje każdą linię, która nie ma pustej linii pod nią, i dodaje jedną. I to wszystko! Możesz zajrzeć do artykułu Power of G na vim wiki, gdzie znajdziesz więcej wymyślnych rzeczy, które możesz zrobić :g(i jest to negatywna siostra :v) - to jedno z tych niesamowicie użytecznych poleceń, na których wkrótce będziesz polegać, a następnie strasznie przegapisz w edytorach które tego nie mają.


1
Dokładnie. Zwykle szukam takich skrótów, :%norm oale okazuje się, że to nie działa zgodnie z przeznaczeniem o. +1
sehe

Wpisz :%s/$/, a następnie naciśnij ^V, a następnie naciśnij Enter.
jpaugh

1
@jpaugh Zakładając, że masz na myśli :%s/$/<C-V><CR><CR>(używać typowego kodowania klawiszy vim-folk), takie podejście po prostu dodaje nową linię po każdej linii. Oznacza to, że linie, które są już oddzielone spacjami (patrz Linia 3 -> Linia 4, w tekście przykładowym), kończą się otrzymywaniem dodatkowych pustych linii. Pierwotnym pytaniem było uniknięcie dodawania dodatkowych pustych linii tam, gdzie już istniały w tekście początkowym.
Trevor Powell,

3

Kiedy testowałem globalne wyszukiwanie @ NeilForester i zastępuję odpowiedź, stwierdziłem, że nie trafiło co sekundę zamierzonej zamiany w kolejnych niepustych liniach, jeśli linie miały tylko jeden znak w każdym. Wydaje się, że jest to spowodowane tym, że wzór zaczyna pasować za każdym razem po ostatnim znaku, który pasował do poprzedniej okazji.

Użycie lookbehind i lookahead rozwiązuje ten problem i sprawia, że ​​wyrażenie regularne jest również nieco krótsze:

:%s/\n\@<!\n\n\@!/\r\r/g

Dzięki! Działa to i nie dodaje więcej linii, jeśli ponownie uruchomię wyszukiwanie (jeśli powiedzmy, dodałem nowe linie do mojego pliku).

1
Czy możesz wyjaśnić, co oznacza każde wyrażenie regularne we wzorcu wyszukiwania? Patrząc na pomoc vima, \n\@<!\noznacza to , że jakikolwiek podział linii, który nie jest zaraz po kolejnym, jest poprawny? Ale nie mogłem zrozumieć, co \n\@!to znaczy. Chciałbym to zrozumieć, abym mógł się nauczyć i zastosować go do innych wzorców wyszukiwania :)

Tak, \n\@<!\noznacza każdy podział linii, który nie następuje natychmiast po kolejnym podziale linii. \n\@!dopasowuje z zerową szerokością, jeśli poprzedni atom (tj. \n) nie pasuje tuż przed tym, co następuje. Spróbuj :help \@<!zobaczyć dokumentację na ten temat w vimie. I
Simon

3

Inny sposób:

%s/\(.\)\n\(.\)/\1\r\r\2/

Co znaczy,

\(.\) match and capture a non-newline character,
\n    match a newline
\(.\) match and capture a non-newline character

zamień na: pierwsze przechwytywanie, podwójne znaki nowego wiersza i drugie przechwytywanie.

Na przykład line1\nLine2wyniki w \1 = 1i \2 = L.


0

Popraw mnie, jeśli się mylę. Myślę, że używasz litery k, gdy jesteś w trybie poleceń, aby przejść w dół linii. Następnie wejdź w tryb wstawiania i dodaj następny wiersz. Powtórzyć w razie potrzeby? Mam nadzieję że to pomoże!


kprzesuwa się w górę linii. jprzesuwa się w dół linii.
Neil Forrester,

Tak, rzeczywiście tak jest. Mój błąd. Dzięki Neil!

0
/[^\n]\n[^\n]
:map <F2> no<esc><F2>

Następnie naciśnij <F2>. Spowoduje to wyszukanie dwóch kolejnych niepustych linii, a następnie wielokrotne dodawanie linii między nimi.

Edytować:

Oto alternatywny sposób, aby to zrobić za pomocą jednego globalnego wyszukiwania i zamiany:

:%s/\([^\n]\)\n\([^\n]\)/\1\r\r\2/g

Mój plik ma wiele linii. Czy istnieje sposób wyszukiwania wyrażeń regularnych i wstawiania pustego wiersza dla całego pliku? Patrzyłem na stackoverflow.com/questions/2673209/…, ale nie mogłem zrozumieć, co oznaczają wszystkie polecenia wyrażenia regularnego.

Zobacz moją powyższą edycję, aby znaleźć alternatywny sposób na osiągnięcie tego samego w jednym poleceniu i bez mapowania rekurencyjnego. Pierwszy sposób powinien jednak działać dla całego pliku.
Neil Forrester,

0

Wypróbuj to polecenie ( 16znaki):

:%!sed G|cat -s

Zamiast próbować „vimgolfa” krótkiego polecenia, pomocne byłoby krótkie wyjaśnienie raczej niejasnych opcji.
Ingo Karkat

0

Nie wiem, jak długi jest twój plik, ale jedną z najprostszych metod jest pisanie ow trybie poleceń. I w następnej linii .. Może to być ładowane do prostego makra.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.