Grundlegende Referenzunterschiede verstehen durch: g / ^ / norm und durch:% norm

8

Nehmen wir an, ich habe die folgende sehr einfache Datei

a
b
c
d
e

und ich habe beschlossen, dass ich nach jeder Zeile leere Zeilen hinzufügen möchte. Mir fallen sofort verschiedene Methoden ein. Wir könnten es einfach tun (und somit das Scheitern annehmen). Wir könnten ein Makro wie aufnehmen qqo<ESC>jqund es mehrmals wiederholen.

Zwei andere Methoden schienen mir damals offensichtlicher.

Erstens dachte ich, ich würde den :normBefehl oin jeder Zeile ausgeben . Also renne ich :%norm o. Was aber tatsächlich passiert, ist, dass wir 5 Leerzeilen erhalten, gefolgt von den nicht getrennten Zeilen wie oben. Ich interpretiere dies so, dass %normvim das Nachrichtenproblem tatsächlich mit dem folgenden normalen Befehl in den ersten fünf Zeilen dieser fünfzeiligen Datei aufgreift . Der oBefehl erstellt eine neue Zeile und vim ist "dumm" in dem Sinne, dass es nach Zeilennummer und nicht nach einer anderen Kennung verweist.

Nun, ich war verlegen. Sicher. Ich habe ein paar andere Dinge versucht, um zu sehen, ob ich die obige Methode zum Laufen bringen kann, aber leider konnte ich nicht. Aus Neugier habe ich meine andere Lieblingsmethode zum Auftragen von Massen ausprobiert. Dies veranlasste mich, es zu versuchen :g/^/norm o. Zu meiner Überraschung funktioniert das ganz gut! Meiner Meinung nach scheint vim hier nicht so "dumm" zu sein wie oben und verweist auf Zeilen nicht nur durch die Zeilennummer.

Was genau ist los?

Davidlowryduda
quelle
2
Nebenbei bemerkt: Sie können es auch so machen: :%s/$/\r/oder so : :%s/\n/\r\r/. Das Mitnehmen ist, dass Zeilenumbrüche abgeglichen werden können \n, aber wie \rin Ersatzwerten geschrieben werden müssen.
lcd047

Antworten:

9

Nun, %ist eine Abkürzung für 1,$(ein Bereich von der ersten bis zur letzten Zeile). Von :he :%:

Line numbers may be specified with:             :range E14 {address}
        {number}        an absolute line number
        .               the current line                          :.
        $               the last line in the file                 :$
        %               equal to 1,$ (the entire file)            :%

Und für :global:

The global commands work by first scanning through the [range] lines and
marking each line where a match occurs (for a multi-line pattern, only the
start of the match matters).
In a second scan the [cmd] is executed for each marked line with its line
number prepended.  For ":v" and ":g!" the command is executed for each not
marked line.  If a line is deleted its mark disappears.

Der erste Fall ist also wie das Durchlaufen einer Liste beim Ändern, sodass ein Zähler für Listenelemente ungültig wird. Im zweiten Fall markieren wir die Elemente, auf die wir in einem Durchgang abzielen möchten, sodass wir auch dann wissen, an welchen Elementen wir arbeiten möchten, wenn die Liste im zweiten Durchgang geändert wird.

muru
quelle
Ah, es ist sogar in der Hilfedatei für global. Wie dumm ich bin. Vielen Dank
Davidlowryduda
Mann - das g ist übertrieben verrückt nützlich. Ich muss mehr Zeit damit verbringen, vom durchschnittlichen vi-Benutzer zum Power-Benutzer zu
wechseln