Zakładając, że twój plik ma oczywiście mniej niż 20000 linii :-)
paxdiablo
3
Właściwie mylisz się Michael. Działa to bezbłędnie, ponieważ VI przestanie uruchamiać makro, gdy tylko osiągnie koniec pliku. Możesz to bardzo łatwo wypróbować z powyższą próbką.
rui
1
Cóż, jak każde makro, które musisz zrobić dobrze za pierwszym razem, ale potem możesz zastosować do dowolnego pliku, wpisując po prostu 10000 @ q. Tak czy inaczej uważam, że to tylko kwestia gustów, więc definitywnie nie mam zamiaru rozpoczynać filozoficznej debaty. :)
rui
3
Wolę używać „makro”. Używając makra, „opisujesz”, w jaki sposób rozwiązałbyś jedno konkretne zadanie i pozwalasz VIMowi je powtórzyć. RUI, wolałbym użyć „j” zamiast klawisza strzałki.
Eleganckim (i wydajnym) sposobem wykonania zadania jest wywołanie :+deletepolecenia usuwającego wiersz następujący po bieżącym, w każdym wierszu za pomocą :globalpolecenia:
Dlaczego ta odpowiedź nie otrzymała więcej głosów pozytywnych? To jest takie czyste i proste. Alternatywnie możesz usunąć pierwszą linię i uruchomić powyższe polecenie, aby usunąć wszystkie nieparzyste linie.
Usagi
3
@Usagi: Dziękuję! Czuję co do tego to samo. I tak, masz absolutną rację, :1d|g/^/+dusuwa nieparzyste linie.
ib.
@Usagi Druga odpowiedź została wybrana jako „najlepsza odpowiedź” 2 lata przed pojawieniem się jego odpowiedzi. Ponadto, chociaż jest to bardziej eleganckie rozwiązanie, mogłoby zostać napisane w bardziej użyteczny sposób (tj. Nie ma wzmianki o tym, co robi ^, podczas gdy makro jest łatwe do zrozumienia dla każdego).
user1271772
3
Przepraszam, ale bez wyjaśnienia, w jaki sposób to polecenie wykonuje pożądane zachowanie, nie głosowałbym go za nim, a zamiast tego wolałbym zaakceptowaną odpowiedź, ponieważ rozumiem, w jaki sposób osiąga cel. To różnica między daniem człowiekowi ryby a nauczeniem go łowienia.
Ta odpowiedź nie przyciąga wystarczającej uwagi, być może z powodu braku wyjaśnienia zarówno tutaj, jak i na połączonym, niechlujnym, ściągawce. polecenie norm uruchamia polecenia trybu normalnego odpowiadające następującym po nim literom. Więc tutaj działa j, aby przejść w dół o linię i dd, aby ją usunąć. Można to uogólnić w linii X, dodając więcej „j” w tym przypadku.
imoatama
5
a% to skrót od 1, $ (wykonaj następujące polecenie od wiersza 1 do końca)
I, Alex, zdecydowanie wolałbym moje rozwiązanie od twojego, ale to warte rozważenia, ponieważ jest to jedyne rozsądne rozwiązanie wykorzystujące tutaj tylko sam vim.
Michael Krelin - haker
Droga makro jest o wiele łatwiejsza.
trusktr
+1 ze względu na elastyczność, z if (expression)jaką działa również dla co trzeciej linii itp.
Jens
5
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)
Nie potrzebujesz -lprzejścia na Perl ... także, powiedziałbym, że awkjest to trochę bardziej rozpowszechnione niż Perl, chociaż obecnie nie jest to dużo więcej i można to zrobić krócej: :%!awk NR\%2lub :%!awk 1-NR\%2dla innych linii.
ephemient
4
:%!awk -- '++c\%2'
alternatywnie
:%!awk -- 'c++\%2'
w zależności od tego, którą połowę chcesz wyeliminować.
Umm, dlaczego nie wykorzystać istniejącej NRzmiennej?
ephemient
Dobrze. Bo o tym zapomniałem. ;-) Ale tak naprawdę „właściwy” wariant będzie jeszcze dłuższy z NR. I nie byłoby dwóch ładnie wyglądających odpowiedników.
Michael Krelin - haker
:%!awk NR\%2lub :%!awk 1-NR\%2, jak napisałem w innym komentarzu. To już niewiele dłużej.
ephemient
1
1-NRjest 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.
Michael Krelin - haker
I NRjest krótszy niż ++c:)
ephemient
3
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
Jest .,/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 gkońcu oznacza powtórzenie podstawienia tak długo, jak długo znajduje się wyrażenie regularne.
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.
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 bjest 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.
:% !sed -e '2~2 d'
^^^^ pipe file through a shell command
^^^^^^ the command is sed, and -e describes an expression as parameter
^^^^^ starting with the second line, delete every second line
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.
źródło
: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:źródło
:1d|g/^/+d
usuwa nieparzyste linie.Możemy użyć
:normal
lub:norm
do wykonania podanych poleceń trybu normalnego. Źródło.źródło
%norm ddj
nie działa, jeśli chcesz usunąć nieparzyste wiersze.Tutaj ^ oznacza CTRL. Makro rekurencyjne do usuwania wiersza co dwa wiersze. Wybierz dobrze swoją pierwszą linię i gotowe.
źródło
z archiwum poczty vim :
(Aby wpisać w jednej linii w linii poleceń vim, usunie wiersz 1,3,5,7, ...)
źródło
!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:
(lub użyj „chyba” zamiast „jeśli”, w zależności od tego, które wiersze chcesz)
źródło
-l
przejścia na Perl ... także, powiedziałbym, żeawk
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.alternatywnie
w zależności od tego, którą połowę chcesz wyeliminować.
źródło
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/
to zakres dla podstawienia. Oznacza „od tej linii do linii, która pasuje do wyrażenia regularnegofff
(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. Nag
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.
źródło
$
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.
b = cb[:]
tymczasowo kopiuje wszystkie linie z bieżącego bufora dob
.b[::2]
pobiera co drugą linię z bufora i przypisuje ją do całego bieżącego buforacb[:]
. Kopiowanie dob
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.
źródło
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.
źródło
Wywołaj sed:
źródło
rozwiązanie
możesz spróbować tego w vimie
edytować
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 zniknieWiem, że jest błotnisty, ale jest vim i działa
źródło