Wie kann ich die Reihenfolge der ausgewählten Zeilen in Vim umkehren?

94

Zum Beispiel, wenn ich vier Zeilen wie folgt habe:

die erste Zeile
die zweite Zeile
die dritte Zeile
die vierte Zeile

Ich möchte sie umkehren

die vierte Zeile
die dritte Zeile
die zweite Zeile
die erste Zeile

Wie könnte ich das in Vim machen?

Jichao
quelle
1
Siehe auch: Alle Zeilen
Palec
1
:command! -bar -range=% Reverse <line1>,<line2>global/^/m<line1>-1 vi.stackexchange.com/a/2107/10254
qeatzy

Antworten:

86

Um alle Zeilen in einer Datei umzukehren,

:g/^/m0

Für eine Erklärung siehe

:help 12.4

Das zeigt auch, wie man nur einen Bereich von Linien umkehrt.

garyjohn
quelle
12
Toller Tipp zum genauen Hilfeabschnitt! Zusammenfassend: 1. Setzen Sie einen Marker in die letzte Zeile, die Sie umkehren möchten (ich benenne den Marker mit 'a' ma). 2. Bewegen Sie den Cursor in die erste Zeile des Blocks. 3. Geben Sie:'a,.g/^/m 'a
Brent Faust
68

Wählen Sie die gewünschten Zeilen aus, drücken Sie !und leiten Sie in der daraufhin angezeigten Eingabeaufforderung die Zeilen durch tacein la :'<,'>!tac. Sehen Sie man tacfür weitere Details.

Rhys Ulerich
quelle
4
Um die Linien auszuwählen, rufen Sie shift+vmit den visuellen Linienmodus jauf und fügen der Auswahl Linien hinzu.
wisbucky
Ich kann bestätigen, dass dies auch in Windows mit funktioniert gvim! Ansonsten musst du absolute Zeilennummern verwenden (vielleicht kannst du relative verwenden, aber du musst vorsichtig sein) mit dem :g/^/m0(was auch sehr schwer zu merken ist) ... Also sollte tac im Grunde genommen mit vim sein, egal auf welcher Plattform du bist dran, ABER es ist nicht 100% Vimscript, ABER wen interessiert das: P
dylnmc
tac ist keine native vim-Behandlung, aber der Befehl 'm'ove nimmt eine Zeilennummer und das ist nicht immer sinnvoll. Ich benutze oft eine Marke als Teil eines Sortiments und :.,'a!tacarbeite daher mit minimalem Aufwand.
Studog
Nach der Verwendung shift+vkönnen Sie }mit zum nächsten Absatz gelangen oder den vertikalen Raum leeren. Auch man tac: concatenate and print files in reverse.
Nilon
33

Unter Mac OS X tacgibt es keine, aber Sie können tail -rmit dem gleichen Effekt arbeiten:

:%!tail -r

Dies funktioniert auch gut für den visuellen Modus:

:'<,'>!tail -r

Auszug aus tail(1)der Manpage von:

Die Option -r bewirkt, dass die Eingabe zeilenweise in umgekehrter Reihenfolge angezeigt wird. Darüber hinaus ändert diese Option die Bedeutung der Optionen -b, -c und -n. Wenn die Option -r angegeben wird, geben diese Optionen die Anzahl der anzuzeigenden Bytes, Zeilen oder 512-Byte-Blöcke anstelle der Bytes, Zeilen oder Blöcke ab dem Anfang oder Ende der Eingabe an, ab der die Anzeige beginnen soll. Die Standardeinstellung für die Option -r ist die Anzeige aller Eingaben.

Thomas Perl
quelle
3
Ausgezeichnet! Um 'tac' unter OS X bereitzustellen:alias tac='tail -r'
Brent Faust
4
Sie können auch brew install coreutilsund verwenden gtac.
Andrew Marshall
1
Genius. Nie daran gedacht, zu verwenden! Befehle für diese Art der visuellen Linienmanipulation.
Charlie Dalsass
3

Für diejenigen, die mit dem visuellen Modus
vertraut sind : 1. Identifizieren Sie die Zeilennummer über der Auswahl, die Sie spiegeln möchten :set nu.
2. Shift-Vum die Auswahl zu markieren, die Sie spiegeln möchten (visueller Modus).
3. :g/^/m <Line number from step 1>.

Beachten Sie, dass es im visuellen Modus automatisch angezeigt wird, :'<,'>g/^/m <Line number>wenn Sie den Befehl von 3 eingeben.

Dieser Befehl verschiebt die Auswahl zeilenweise in die von Ihnen angegebene Zeilennummer. Wenn der zweite Eintrag in die angegebene Zeilennummer verschoben wird, wird der erste nach unten auf Zeilennummer + 1 verschoben. Der dritte drückt den ersten und den zweiten nach unten usw., bis die gesamte Liste in die einzelne Zeilennummer verschoben wurde Liste in umgekehrter Reihenfolge.

Horta
quelle
4
Sie können die '<anstelle der manuellen Eingabe der Zeilennummer verwenden. Starten Sie die Auswahl einfach eine Zeile früher und führen Sie sie aus :'<,'>g/^/m'<.
Palec
3

Ein Befehl :Rev[erse]und optionale Zuordnungen für Ihre vimrc, damit Sie sich die nicht offensichtlichen Schritte dieses Rezepts nicht merken und ausführen müssen:

" Reverse the lines of the whole file or a visually highlighted block.
    " :Rev is a shorter prefix you can use.
    " Adapted from http://tech.groups.yahoo.com/group/vim/message/34305
command! -nargs=0 -bar -range=% Reverse
    \       let save_mark_t = getpos("'t")
    \<bar>      <line2>kt
    \<bar>      exe "<line1>,<line2>g/^/m't"
    \<bar>  call setpos("'t", save_mark_t)

nmap <Leader>r :Reverse<CR>
xmap <Leader>r :Reverse<CR>

( Zuordnungen :xmapfür den visuellen, aber nicht den Auswahlmodus, wie :help mapmode-xzum Zuordnen druckbarer Zeichen empfohlen.)

(Basierend auf: http://tech.groups.yahoo.com/group/vim/message/34305 )

Aaron Thoma
quelle
Dies sollte die akzeptierte Antwort IMO sein. Am nützlichsten und ich muss mich nicht erinnern :'<,'>g/^/m'<:)
Eliot
1
@ Eliot, danke! :) (Ich habe ein bisschen 'Bonus-Inhalt' hinzugefügt.;))
Aaron Thoma
Wie kann ich in diesem Fall sagen, dass die Auswahl bei -1 beginnt? Weil der Umzug an diesem Punkt beginnt.
SergioAraujo
@ SergioAraujo: Ist so etwas wie das, :-1,+1Revwas du suchst? Stellen Sie sicher, dass Sie den Bereich, den Sie umkehren möchten, visuell auswählen können, z V7j:Rev. Wenn dies Ihre Frage nicht beantwortet, habe ich sie nicht verstanden, daher müssen Sie sie für mich ausarbeiten oder umformulieren.
Aaron Thoma
1

Angenommen, Sie befinden sich in Zeile 3, daher haben wir einen Bereich von 3 bis 6. Geben Sie einfach ein.

:3,6g/^/m2
SergioAraujo
quelle
1
Sie können die Nummer der aktuellen Zeile implizit belassen: Wenn sich der Cursor in der ersten Zeile Ihres Bereichs befindet, können Sie auf kürzen :,6g/^/m2. oder wenn in dem letzten Zeile des Bereichs: :3,g/^/m2; und :3,6g/^/m2funktioniert von überall in der Datei.
Aaron Thoma