Wie kann ich fortlaufende Zahlen in einem Ex-Ersatzbefehl verwenden?


8

Angenommen, ich möchte vor jeder Zeile, die mit dem Wort "Do" beginnt, eine Zahl einfügen. Der Befehl würde ungefähr so ​​aussehen :%s/^(Do )/1. \1/, aber was kann ich tun, damit jedes Mal nacheinander Zahlen anstelle derselben Zahl angewendet werden?

Beachten Sie, dass ich mir der zahlreichen Möglichkeiten bewusst bin, dies mit Makros und Strg-A zu tun, aber für die Verwendung in komplizierteren Ex-Modus-Befehlen möchte ich die Antwort auf genau die Titelfrage wissen.

Für ein anderes Beispiel, bei dem ein Makroansatz nicht so einfach wäre, nehmen wir an, ich möchte allen Instanzen des Wortes "Abschnitt" eine Nummer hinzufügen und sie fortlaufend nummerieren lassen, aber die Zählung nach jeder Zeile, die mit "Kapitel" beginnt, neu starten. Ein Ex-Modus-Befehl, der dies fast kann, abgesehen davon, dass die hinzuzufügende Zahl tatsächlich erhöht wird, lautet:

:g/^Chapter/;/^Chapter/-s/Section\zs/ 1/g

Sie können sehen, dass eine einfache Methode zum Inkrementieren von Zahlen im Ex-Modus-Ersatzbefehl sehr nützlich sein kann.

Antworten:


8

Dieser Befehl macht was Sie wollen:

:let i = 1|g/^Do/s/^/\=i/|let i = i + 1

Erläuterung…

  • let i = 1initialisiert Zähler i,
  • g/^Do/s/^/\=i/steht ivor jeder Zeile, beginnend mit Do,
  • let i = i + 1Inkremente i.

Der Trick ist, dass die Inkrementierung vor der nächsten Ersetzung erfolgt.

--- bearbeiten ---

Wenn wir eine einzelne Substitution verwenden würden, würde der Zähler nur einmal erhöht, nachdem alles erledigt ist.

Da wir mehrere Substitutionen durchführen - eine für jede übereinstimmende Zeile - anstelle einer einzelnen, wird der Zähler vor der nächsten Substitution korrekt inkrementiert.


Wie können Sie einen Punkt nach der Zahl setzen? \=i. ist ein ungültiger Ausdruck.
David Conrad

2
@DavidConrad .wird zu einem verketteten Operator im \=Ausdruck. Also s//\=i . '. '/wird '. ' Check out anhängen :help expression-syntax.
Wildcard

Inkrementierung erfolgt nach der Substitution
Christian Brabandt

@ChristianBrabandt, oops ich versehentlich ein Wort.
Romainl
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.