Wie füge ich einer Datei permanente Zeilennummern hinzu?

Ich habe eine Textdatei wie diese (unter Verwendung von gVim unter Windows)

foo bar baz quux corge grault garply waldo fred plugh [...150 more lines...] xyzzy thud 

Ich möchte jeder Zeile in der Datei eine Nummer hinzufügen. Verwenden Sie nicht :set number, sondern fügen Sie die Nummer wie folgt als Text vor jeder Zeile hinzu, damit die Nummer Teil der Datei ist.

1. foo bar baz quux 2. corge grault garply 3. waldo fred plugh [...~150 more lines...] 155. xyzzy thud 

Kommentare

  • awk ist wahrscheinlich das Werkzeug für diesen Job. Aber ich ‚ bin unter Windows (seufz).
  • Beantwortet hier bereits , egal 🙂
  • Vielleicht .. Oder ist das allgemeiner?
  • Es ist ‚ ähnlich, aber ich würde nicht ‚ weiß nicht, was permanente Zeilennummern sind. Zweitens betrifft die andere Frage alle Zeilen (und die Antwort tut dies) speziell für gVim unter Windows, und dies ist eine einfache nummerierte Liste für einen Absatz nur in einfachem vim.
  • Nun, ich denke, dieser Beitrag verwendet “ permanent “ zeigt nicht an, dass der Puffer geändert werden soll und dass die Nummern nicht ‚ sind t eine rein visuelle Sache (genau wie Sie). Der Grund für die Angabe von gvim unter Windows besteht darin, externe Dienstprogramme wie cat oder nl zu vermeiden, die Zahlenzeilen ausführen können, aber keine ‚ ist unter Windows nicht allgemein verfügbar (wie aus dem Kommentar zu awk hervorgeht). Die beiden besten Lösungen sind reine Vim. Schließlich sind alle Zeilen gegen einen Absatz nur eine Frage der Bereichsauswahl. Offensichtlich kein großes Problem.

Antwort

Auf reine Vim-Art:

:%s/^/\=line(".").". " 

Erläuterung:

:%s/^/ " the substitution will be applied to the beginning of every line \= " the rest of the replacement part is an expression line(".").". " " the expression returns the current line number concatenated with a dot and a space 

Siehe :help \= und :help line().

Die Verwendung eines Ausdrucks im Ersatzteil ist sehr leistungsfähig und FWIW ein ziemlich guter Einstiegspunkt in Vimscript.

Kommentare

  • Wie kann ich diesen sehr nützlichen Befehl zu einer Keymap in vimrc hinzufügen?
  • So gelangen Sie zum Thema der vim-Hilfe zum Ersetzen: :help sub-replace-expression

Antwort

Eine schöne Sache an Vim-Makros ist, dass sie sich wiederholen können (sie können sich selbst aufrufen) ):

  1. Löschen Sie das Register q: qqq
  2. Fügen Sie die Nummer in die erste Zeile ein: ggI1. (Leerzeichen nicht vergessen!)
  3. Gehen Sie zurück zum Zeilenanfang und beginnen Sie mit der Aufnahme eines Makros: 0qq
  4. Kopieren Sie die Nummer:
  5. Gehen Sie eine Zeile nach unten und fügen Sie die Nummer ein: +P
  6. Gehen Sie zurück zum Zeilenanfang und erhöhen Sie die Zahl: 0<c-a>
  7. Gehen Sie zurück zum Zeilenanfang (damit das Makro nicht bricht, wenn es zweistellig wird!): 0
  8. Rufen Sie das Makro einmal auf, um es rekursiv zu machen. Zu diesem Zeitpunkt befindet sich noch nichts im Register q, sodass nichts passiert: @q.
  9. Speichern Sie das Makro: q
  10. Rufe das Makro noch einmal auf und beobachte, wie die Funken fliegen!: @@

Das Makro wird Rufen Sie sich dann weiter auf, bis das Ende der Datei erreicht ist.

Sie können den rekursiven Makrotrick für viele andere ähnliche Probleme verwenden, daher ist es „gut, sich dessen bewusst zu sein.

Wenn Sie aus irgendeinem Grund kein rekursives Makro verwenden möchten, können Sie die Schritte 1 und 8 weglassen und eine Anzahl verwenden, um das Makro mehrmals auszuführen, z 100@q führt das Makro q 100 Mal aus.

Kommentare

  • Mächtiges Zeug, ich verneige mich vor deiner Meisterschaft. Makros sind für mich wie schwarze Magie …
  • @ropata, ein Makro ist nur eine Folge von (meistens) Befehlen im Normalmodus.
  • @romainl Ich denke, es ist ‚ ist es besser, es als eine Folge von Tastenanschlägen zu betrachten.
  • @Rich, es kann eine Folge von vielen Dingen sein, einschließlich Ex-Befehlen.
  • @romainl Ja, das ist ‚, weshalb ich denke, dass es ‚ am besten ist, es als Tastenanschläge zu betrachten. Es gibt genau das wieder, was Sie auf der Tastatur eingeben (einschließlich, wie Sie sagen, ex-Befehle), als hätten Sie alles manuell eingegeben.

Antwort

Ich verwende gerne den Befehl vim global, um Aufgaben wie diese auszuführen. Dies gilt für das Hinzufügen von Iterationen am Zeilenanfang oder für das Ändern eines Symbols im Text. Es sieht komplizierter aus als die anderen Lösungen, ist jedoch ein ziemlich flexibles Muster, das Sie verwenden können, wenn Sie es zur Hand haben. Es lässt sich leicht und ohne viel Nachdenken ändern.

Wählen Sie zunächst Ihren Bereich aus (welche Linien Sie verwenden) möchte dies anwenden). Ich benutze normalerweise Markierungen (z.ma in der ersten Zeile und mb in der zweiten Zeile, aber Sie können auch Zeilennummern oder visuelle Auswahl verwenden), und geben Sie dann eine Änderung von ein Der folgende Befehl (derzeit für Ihren Anwendungsfall optimiert)

:let i=1|"a,"bg/^/s/^/\=i.". "/|let i=i+1 

Dekonstruktion

:let i=1 

Dadurch wird die Variable i mit einem Startwert eingerichtet. Normalerweise beginnen Listen mit 1, daher setze ich i auf 1.

| 

Die Leiste startet einen neuen Befehl

"a,"b 

Hiermit wird der Bereich des nächsten Befehls festgelegt. Ich gehe von mark a zu mark b Dies wird in der ersten und letzten Zeile Ihrer Liste festgelegt.

g/^/ 

Dies ist der globale Befehl. Es durchsucht die Datei (oder den Bereich) nach einem bestimmten regulären Ausdruck und führt den Rest der Befehlszeile in jeder der übereinstimmenden Zeilen aus. Ich stimme mit jeder Zeile überein, indem ich nach „Zeilenanfang“ suche. Wenn Sie Text wie

Item some txt other text Item second item whatever Item third 

hatten und diese Beschriftungen nur vor Item und ignorieren Sie die anderen Zeilen. Führen Sie stattdessen g/Item/ oder g/^Item/ aus (unter der Annahme des wörtlichen Elementtextes) )

s/^/\=i.". "/ 

Hiermit wird der reguläre Ausdruck ausgeführt, um den Zeilenanfang durch den Wert von i zu ersetzen a .. Im Allgemeinen können Sie dies für alles tun (ersetzen Sie beispielsweise die Bezeichnung Item durch die Nummer).

|let i=i+1 

Obwohl die Leiste einen neuen Befehl startet, richtet sie einen zweiten Befehl ein, der innerhalb des globalen Befehls ausgeführt wird, anstatt nach Abschluss des globalen Befehls. Das Ergebnis ist, dass wir i bevor die nächste Zeile von g verarbeitet wird. Hier ist ein weiterer Ort der Flexibilität. Die Änderung von i kann alles sein (inkr Rufen Sie mit 2 eine Funktion auf, die das nächste Element der Fibonacci-Sequenz generiert.

Antwort

Fügen Sie Zahlen hinzu alle Zeilen

Es ist möglich, :%!nl -ba oder :%!cat -n Befehle, mit denen allen Zeilen Zeilennummern hinzugefügt werden.

Unter Windows können Sie „Cygwin / MSYS / SUA muss installiert sein.

Hinzufügen zu ausgewählten Zeilen

Um nur Nummern für ausgewählte Zeilen hinzuzufügen, wählen Sie diese bitte in aus visueller Modus ( v und Cursor). Wenn Sie fertig sind, führen Sie den folgenden Befehl aus: :%!nl (Leerzeilen ignorieren) oder :%!cat -n (einschließlich Leerzeilen).

Formatierung

Um zusätzliche Leerzeichen zu entfernen, wählen Sie sie im visuellen Block aus ( Strg + v ) und entfernen Sie sie ( x ).

Um einige Zeichen hinzuzufügen (., :, ) Wählen Sie sie nach den Zahlen im visuellen Block aus ( Strg + v ) und fügen Sie dann das Zeichen ( A hinzu) Geben Sie das Zeichen ein und beenden Sie den Vorgang mit Esc ).

Kommentare

  • Dies ergibt nicht die gleiche Formatierung wie angegeben in der Frage. Ich mag jedoch die Einfachheit der Lösung.
  • @KarlYngveLerv å g Vielen Dank, dies wurde in die Antwort aufgenommen.

Antwort

Eine Änderung der Antwort von romainl :

:%s/^\(\d\+\. \)\?/\=line(".").". " 

Dies fügt nicht nur Zeilennummern hinzu, sondern ersetzt auch bestehende Zeilennummern, wenn sie bereits vorhanden sind. Wenn Sie eine Zeile auf halbem Weg eingefügt haben, wird alles wie erwartet neu nummeriert.

Dies funktioniert, indem eine beliebige Zahl gefolgt von einem. Und einem Leerzeichen am Zeilenanfang durch eine neue Zahl ersetzt wird Dies wird offensichtlich unterbrochen, wenn Sie eine Zeile haben, die bereits mit diesem Muster beginnt. Verwenden Sie sie daher mit Bedacht.

Der hinzugefügte Teil:

  • ^ – Zeilenanfang
  • \( – Neue Untergruppe starten
  • \d\+ – Eine Ziffer einmal oder mehrmals abgleichen
  • \. – Einen Punkt abgleichen (.) und ein Leerzeichen .
  • \) – Untergruppe beenden
  • \? – Machen Sie die Gruppe optional, so dass sie wie zuvor funktioniert, wenn noch keine Nummer in dieser Zeile steht.

Bonushinweis :
Um die Zeilennummern zu entfernen , können Sie dasselbe Muster mit leerem Repalce-Teil verwenden:

:%s/^\(\d\+\. \)\?// 

Antwort

I1. <esc>^qqyWjP^<C-a>q 

Dies nummeriert die ersten beiden Zeilen und Sie können @q, um nachfolgende Zeilen zu nummerieren (oder geben Sie ex ein. 18@q, wenn Sie insgesamt 20 Zeilen nummerieren möchten).

Erläuterung:

I1. <esc> Number the first line hqq Go back to the start of the line and start recording a macro yWjP Copy the line number to the next line ^<C-a> Increment the next line"s line number q Finish recording 

Dies hat den Vorteil, dass keine externen Befehle erforderlich sind. Dies ist hilfreich, wenn Sie dies tun Arbeiten Sie beispielsweise mit Vim unter Windows.

Kommentare

  • Nach Eingabe von 1. <esc>h befinden Sie sich auf der zweite Spalte, nicht erste Spalte. Ich würde die h durch 0 ersetzen. Danach sollte Ihre Lösung meiner Meinung nach sehr gut sein.
  • @KarlYngveLerv å g Hoppla, das war ein Tippfehler. Danke, behoben.
  • Kein Problem. Sie haben die Erklärung jedoch noch nicht aktualisiert. Außerdem: Auf vielen Tastaturen wartet ^ auf ein zweites Zeichen, um Tippkombinationen wie ^a -> â zu ermöglichen. Ich bin immer noch der Meinung, dass dies die beste Lösung ist, aber ich denke, dies sollte auch erwähnt werden.

Antwort

I. Ich denke, die gewählte Antwort ist die beste, aber im Geiste der Vielfalt biete ich eine Alternative mit einem externen Programm an:

:%!cat -n 

Dies filtert Ihr gesamtes Puffer (wie durch % bezeichnet) durch das externe Programm cat, wobei die -n Das Flag stellt jeder Eingabezeile eine Zeilennummer voran.

Dies setzt natürlich voraus, dass Sie cat installiert haben, was (wahrscheinlich) für alle Unix-Versionen gilt -ähnliche Systeme.

Weitere Informationen zum Filtern durch externe Programme finden Sie unter :help :range!.

Kommentare

  • Mir ist klar, dass der Fragesteller gVim unter Windows verwendet, daher wird diese Lösung dort wahrscheinlich nicht ‚ funktionieren. Ich denke jedoch, dass sie noch einige Möglichkeiten für andere bietet t o daraus lernen.
  • Wenn Sie ‚ msysgit installiert und dies Ihrem PATH hinzugefügt haben (IIRC it ‚ ist eine Installationsoption), diese Lösung sollte auch unter Windows funktionieren.
  • cat -n ist nicht POSIX, aber nl ist es, also könnte es ein sein Bessere Option.

Antwort

Eine etwas hackige Lösung könnte die folgende sein (alles, was zwischen < und> müssen nach Drücken von Strg + v ) eingefügt werden:

:%normal :redir @"<Enter>:-=<Enter>:redir END<Enter>I<C-R>".<Tab><Esc>kdd 

Dekonstruktion

:%normal {commands} 

führt den Normalmodusbefehl in jeder durch den Bereich angegebenen Zeile aus, in diesem Fall in jeder Zeile

:redir @" 

leitet jede Ausgabe von ex-Befehlen an den unbenannten Puffer um.

:.= 

ist ein ex-Befehl, der die aktuelle Zeile ausgibt Nummer (leider mit einer vorangegangenen neuen Zeile)

:redir END 

beendet die Umleitung zum unbenannten Puffer

I<C-R>".<Tab><Esc> 

fügt den Inhalt des unbenannten Puffers mit a ein. und eine Registerkarte vor jeder Zeile, die den Einfügemodus verlässt.

kdd 

geht eine Zeile nach oben und entfernt die neue Zeile, die das Ergebnis von: ist. = Befehl.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.