Jak to zrobić w Vimie:
PRZED:
aaa
bbb
ccc
ddd
eee
fff
PO:
aaa
ccc
eee
Jak to zrobić w Vimie:
PRZED:
aaa
bbb
ccc
ddd
eee
fff
PO:
aaa
ccc
eee
Odpowiedzi:
Możesz do tego użyć makra. Wykonaj następujące czynności.
gg
.qq
.dd
po.q
.10000@q
PS: Aby przejść do trybu poleceń, po prostu naciśnij klawisz Escape kilka razy.
:g/^/+d
z user stackoverflow.com/users/254635/ib (poniżej) to bardziej elegancki sposób rozwiązania tego problemu.
Eleganckim (i wydajnym) sposobem wykonania zadania jest wywołanie :+delete
polecenia usuwającego wiersz następujący po bieżącym, w każdym wierszu za pomocą :global
polecenia:
:g/^/+d
:1d|g/^/+d
usuwa nieparzyste linie.
Możemy użyć :normal
lub :norm
do wykonania podanych poleceń trybu normalnego. Źródło.
:%norm jdd
%norm ddj
nie działa, jeśli chcesz usunąć nieparzyste wiersze.
:map ^o ddj^o
^o
Tutaj ^ oznacza CTRL. Makro rekurencyjne do usuwania wiersza co dwa wiersze. Wybierz dobrze swoją pierwszą linię i gotowe.
:let i=1 | while i <= line('$') | if (i % 2) | exe i . "delete" | endif | let i += 1 | endwhile
(Aby wpisać w jednej linii w linii poleceń vim, usunie wiersz 1,3,5,7, ...)
!perl -ne 'print unless $. % 2'
:-)
if (expression)
jaką działa również dla co trzeciej linii itp.
Zawsze możesz przesłać potokiem przez polecenie powłoki, co oznacza, że możesz użyć dowolnego języka skryptowego:
:%!perl -nle 'print if $. % 2'
(lub użyj „chyba” zamiast „jeśli”, w zależności od tego, które wiersze chcesz)
-l
przejścia na Perl ... także, powiedziałbym, że awk
jest to trochę bardziej rozpowszechnione niż Perl, chociaż obecnie nie jest to dużo więcej i można to zrobić krócej: :%!awk NR\%2
lub :%!awk 1-NR\%2
dla innych linii.
:%!awk -- '++c\%2'
alternatywnie
:%!awk -- 'c++\%2'
w zależności od tego, którą połowę chcesz wyeliminować.
NR
zmiennej?
:%!awk NR\%2
lub :%!awk 1-NR\%2
, jak napisałem w innym komentarzu. To już niewiele dłużej.
1-NR
jest dłuższy niż c++
. Tak, wiem, że to jedna postać. Jak powiedziałem - prawdziwy powód jest taki, że o tym zapomniałem. W każdym razie wygląda na to, że ludzie nie doceniają tutaj piękna awk.
NR
jest krótszy niż ++c
:)
Możesz użyć własnych możliwości wyszukiwania i zamiany Vima, jak na przykład: Umieść kursor w pierwszej linii i wpisz w normalnym trybie:
:.,/fff/s/\n.*\(\n.*\)/\1/g
.,/fff/
to zakres dla podstawienia. Oznacza „od tej linii do linii, która pasuje do wyrażenia regularnego fff
(w tym przypadku do ostatniej linii).s///
jest poleceniem zastępczym. Szuka wyrażenia regularnego i zastępuje każde jego wystąpienie łańcuchem. Na g
końcu oznacza powtórzenie podstawienia tak długo, jak długo znajduje się wyrażenie regularne.\n.*\(\n.*\)
dopasowuje nową linię, następnie całą linię ( .*
dopasowuje dowolną liczbę znaków oprócz nowej linii), a następnie kolejną nową linię i kolejną linię. Nawiasy \(
i \)
powodują zapisanie zawartego w nich wyrażenia, dzięki czemu możemy go później użyć za pomocą \1
.\1
wstawia zgrupowany znak nowej linii i wiersz po nim z powrotem, ponieważ nie chcemy, aby następna linia również zniknęła - po prostu chcemy, aby mechanizm podstawiania przeszedł obok niego, więc nie usuwamy go przy następnej zamianie.W ten sposób możesz kontrolować zakres, w którym ma nastąpić usunięcie, i nie musisz używać żadnego zewnętrznego narzędzia.
$
zamiast tego /fff/
dla końca pliku, niezależnie od zawartości pliku.
Jako inne podejście możesz również użyć Pythona, jeśli twój vim ma na to wsparcie.
:py import vim; cb = vim.current.buffer; b = cb[:]; cb[:] = b[::2]
b = cb[:]
tymczasowo kopiuje wszystkie linie z bieżącego bufora do b
. b[::2]
pobiera co drugą linię z bufora i przypisuje ją do całego bieżącego bufora cb[:]
. Kopiowanie do b
jest konieczne, ponieważ obiekty bufora nie obsługują rozszerzonej składni wycinka.
Prawdopodobnie nie jest to „sposób Vima”, ale może być łatwiejszy do zapamiętania, jeśli znasz Pythona.
Aby usunąć nieparzyste linie (1, 3, 5, ..) -> :%s/\(.*\)\n\(.*\)\n/\2\r/g
Aby usunąć parzyste linie (2, 4, 6, ..) -> :%s/\(.*\)\n.*\n/\1\r/g
Wyszukaj tekst (tworzy pierwszą linię), po którym następuje znak nowego wiersza i trochę więcej tekstu (tworzy drugą linię), a następnie inny znak nowego wiersza i zamień powyższe na pierwszą zgodność (nieparzysta linia) lub drugą zgodność (parzysta linia) po którym następuje powrót karetki.
możesz spróbować tego w vimie
:1,$-1g/^/+1d
Spróbuję wyrazić się bardziej jasno (dwie części)
pierwsza część zakres wyboru ( :from,to
)
druga część akcja ( d
usuń)
:1,$-1
)g
) delete ( +1d
) następny wierszmożesz spróbować przejść do pierwszej linii pliku i wykonać :+1d
, a następna linia zniknie
Wiem, że jest błotnisty, ale jest vim i działa