Wie kann ich die Reihenfolge der Zeilen umkehren, sodass die erste Zeile am Ende und die letzte Zeile zuerst angezeigt wird? (Dies können alle Zeilen in einem Puffer, ein Adressbereich oder eine zeilenweise Auswahl des visuellen Modus sein.)
Ich möchte mich verwandeln
rat
ox
tiger
⋮
dog
pig
in
pig
dog
⋮
tiger
ox
rat
ohne auf einen externen Befehl wie tac
.
rearrangement
200_erfolg
quelle
quelle
Antworten:
Die Kraft des Globalen wird hier wirken:
Oder einfacher (danke @tommcdo)
Die erste Zeile entspricht jeder Zeile. Löschen Sie sie für jede Zeile und fügen Sie sie oben in die Datei ein. Beim Durchlaufen der Datei wird der Text umgekehrt.
Die zweite Zeile stimmt auf ähnliche Weise mit jeder Zeile überein und verschiebt sie an den Anfang der Datei.
Hinweis: Diese beiden Methoden wirken sich auf die gesamte Datei aus und gelten nicht ordnungsgemäß für das Umkehren einer Teilmenge der Zeilen. Siehe Ingo Karkats Antwort für eine Lösung, die in einem bestimmten Bereich funktioniert.
Beschreibung:
g
globaler Befehl/^/
jede Zeile übereinstimmen , die einen Anfang hat (dh alle Leitungen)exe
führt die folgenden Zeichenfolge"normal
auszuführen normaler Modus befiehltdd
Zeile löschtgg
Bewegung zu Anfang der DateiP
Paste über aktuelle Positionmove 0
Verschiebt die aktuelle Zeile unter Zeile 0 (wodurch sie an Position 1 oder in die erste Zeile der Datei verschoben wird).quelle
:normal
Befehls können wir den Ex-Befehl verwenden:move 0
, der die Zeile an den Anfang des Puffers verschiebt.:execute
ist nur notwendig, wenn der Befehl dynamisch aufgebaut werden muss, z:execute 'normal' g:user_command
.:execute
weil ich später oft andere Ex-Befehle nach dem vorhandenen anhänge, und es ist für mich bequemer, das:exe
bereits zu haben, als es später zurückgehen und einfügen zu müssen. Leider ist diese Gewohnheit in diese Antwort eingeflossen, in der sie nicht so häufig vorkommt.:execute
: Da es sich um eine Zeichenfolge handelt, wird klar umrissen, wo die Befehle im Normalmodus enden, obwohl ich die Zeichenfolge nicht konstruiere. Es ist für mich einfacher, ausgeglichene Anführungszeichen zu finden, als danach zu suchen<esc>
oder was auch immer, um den Modus zu beenden. Auch dies ist persönliche Präferenz und Gewohnheit. :-):9,11g/^/move 8
... Die letzte Zahl muss der Anfang des Bereichs minus 1 sein (angepasst an Ingos Antwort).Dieser Einzeiler (für Sie
~/.vimrc
) definiert einen:Reverse
Befehl. Sie können den:global
Teil auch direkt verwenden, aber die Syntax von:move
(die die Zeilen iterativ vor dem Beginn des Bereichs verschiebt und dadurch umkehrt) ist nicht leicht zu merken:quelle
<line1>
&<line2>
erforderlich, damit dies in einem Bereich funktioniert, dh:7,9Reverse
(sie sind Merkmale voncommand
, nichtglobal
odermove
). Der einfachere:command! -bar -range=% Reverse :global/^/m 0
wird auch funktionieren, aber nur für den gesamten Puffer ...Pure Vim:
Erläuterung:
Quelle: Alle Linien und Potenzen von g bei vim wikia umkehren.
Einige Beispiele mit externen Befehlen:
tac
(Teil von GNU coreutils -cat
umgekehrt):tail
unter BSD / OSX (nicht POSIX-konform):Weitere Ideen finden Sie unter:
quelle
:g/^/m0
dasselbe wie:g/^/move 0
, was ist Johns Antwort?tac
). Aber ich vermute, die Ablehnung lag daran, dass die Antwort wiederholt wurde.tac
von OP erwähnt wurde, aber alle anderen ähnlichen Fragen würden sowieso doppelt vorkommen, daher ist es gut, es noch einmal zu erwähnen. John hat dieses Cmd von @tommcdo comment übernommen. Ich habe es ursprünglich von DerMike übernommen , aber ich glaube, er hat es einfach von wikia übernommen, also habe ich vim wikia Credits gegeben, damit es nicht vollständig dupliziert wird, da die Erklärung völlig anders ist.Im Sinne von funktionalem VimL:
getline(1, line('$'))
gibt eine Liste aller Zeilen im Puffer zurück.'$'
ist ein spezielles Argument,line()
das die letzte Zeile im Puffer angibt.reverse(...)
Kehrt die Eingabeliste vor Ort um. Man müsste verwenden,reverse(copy(...))
wenn die Eingabeliste nicht geändert werden soll.setline(1, ...)
Ersetzt die angegebene Zeile durch das zweite Argument. Wenn das zweite Argument eine Liste ist, wird die gleiche Anzahl von Zeilen wie die Länge der Liste durch den Inhalt der Liste ersetzt.Wenn Sie möchten, können Sie auch einen Befehl definieren, der einen Bereich einnimmt (Standard-
%
Gesamtpuffer).quelle
hlsearch
aktiviert), wie der:g/
Befehl aus den anderen Antworten ... Ist die Leistung vielleicht schlechter? Dagetline(1, line('$'))
bekommt man den gesamten Puffer im Speicher.reverse()
scheint vorhanden zu sein, so dass als solches nur sehr wenig Speicher benötigt wird ...Gemäß der Vim-Dokumentation usr_12.txt - Clevere Tricks
quelle
Relative Zahlen verwenden. Der Absatz beginnt in Zeile 13 und spammt weitere 4 Zeilen
quelle