Zeilen nummerieren, damit mehrere Leute denselben Text prüfen können
Veröffentlicht am 12.8.2026 · 14 Min. Lesezeit · Text- & Sprach-Tools
Daniel Okonkwo — Front-end-Entwickler und Tech-Redakteur bei OneKitly
Web-Performance · Dateiformate
Anhand von 3 Quellen geprüft
Füge den Text in add-line-numbers ein, und jede Zeile bekommt eine Nummer davor, beginnend bei 1. Das Feld „Beginnen bei“ nimmt andere Werte an, aber keine Null: Der Code liest Number(start) || 1, und 0 ist falsy, also wird aus 0 wieder 1. Negative Startwerte funktionieren — setze −3 auf drei Zeilen und du bekommst −3, −2, −1. Die Ausrichtung geschieht automatisch mit Leerzeichen, nie mit führenden Nullen: Die Breite ergibt sich aus der letzten Nummer, also liefern 102 Zeilen „ 1. “ bis „102. “, und ein Text mit 99 Zeilen liefert „ 1. “ mit einem Leerzeichen. Standardtrennzeichen ist ein Punkt mit Leerzeichen; zehn weitere stehen zur Wahl, darunter „1) “, „1: “, „[1] “, „#1 “ und ein Tab. Der Rückweg ist unsymmetrisch, aber nicht mehr zerstörerisch. remove-line-numbers kennt genau ein Muster — führender Leerraum, Ziffern, ein Trennzeichen aus einem Satz von acht, dann ein einzelnes Leerzeichen oder das Zeilenende — macht also acht der elf rückgängig und lässt Strich, senkrechten Strich und einfaches Leerzeichen absichtlich stehen: „10 - 20 people“ und „1 | Alice | 30“ sind weit häufiger Inhalt als Nummerierung. Weil es nun genau ein Leerzeichen nimmt statt einer gierigen Folge, kommt eingerücktes JavaScript nach dem Nummerieren und Entnummerieren Byte für Byte zurück, Einrückung inklusive. Und weil auf ein Trennzeichen ein Leerzeichen folgen muss, bleiben „3.14 is pi“ und „12.50 Coffee“ unangetastet. Was keine Regel retten kann, ist eine Zeile, die genau wie die eigene Ausgabe des Werkzeugs aussieht: Aus „2026. A year.“ wird weiterhin „A year.“ Nummeriere eine Kopie, behalte das Original.
Die Nummerierung beginnt bei 1 und lässt sich nicht auf 0 setzen, ausgerichtet wird mit Leerzeichen statt Nullen, und das Entfernen macht acht der elf Trennzeichen rückgängig, ohne die Einrückung anzutasten. Was es weiterhin nicht kann: deine Zahlen von seinen unterscheiden.
Warum ein geteilter Text überhaupt Nummern braucht
Code kommt mit Nummern. Der Editor druckt sie in den linken Rand, ein Diff druckt sie zu beiden Seiten der Änderung, und ein Review-Kommentar auf einer Hosting-Plattform hängt sich an eine davon. Prosa nicht. Eine Vertragsklausel, ein Satz Untertitel, ein Export aus einem Translation Memory, eine Liste von Produktnamen, die zwei Kolleginnen prüfen sollen — keiner dieser Texte hat eine stabile Art zu sagen „der vierte von oben“, außer zu zählen.
Beim Zählen von Hand geht die Durchsicht schief. Zwei Leute zählen von verschiedenen Stellen aus, die eine rechnet die Leerzeile mit, die andere nicht, und eine Stunde später gibt es zwei Änderungen an derselben Klausel und eine an einer Klausel, die niemand anfassen wollte. Jeder Zeile vor dem Verschicken eine Nummer zu geben räumt diese ganze Sorte Missverständnis für den Preis eines Einfügens aus.
Das wichtige Wort ist „vorher“. Nummern sind ein Koordinatensystem, und ein Koordinatensystem nützt nur, solange es stillsteht. Nummeriert jemand einen bereits kommentierten Text neu, wird jeder Kommentar zur Rätselfrage. Einmal nummerieren, genau diese Fassung verschicken und die Änderungen dagegen einsammeln.
Was das Werkzeug tatsächlich erzeugt
Standard ist ein Punkt mit Leerzeichen: aus „first line“ wird „1. first line“. Zehn weitere Trennzeichen stehen bereit — „1) “, „1: “, „1 - “, „1 | “, „[1] “, „1] “, „#1 “, „1 → “, ein einfaches Leerzeichen und ein Tab. Zwei davon umschließen die Nummer, statt ihr zu folgen, weshalb „[1] “ und „#1 “ anders aussehen als der Rest.
Die Ausrichtung wird aus der letzten Nummer bestimmt und mit gewöhnlichen Leerzeichen umgesetzt, nicht mit Nullen. Ein Text mit 102 Zeilen kommt oben mit „ 1. line1“ und unten mit „102. line102“ zurück, die Ziffern rechtsbündig. Die Breite wird einmal festgelegt, vor der ersten Zeile: 99 Zeilen ergeben Breite zwei, 100 Zeilen Breite drei — ein zusätzliches führendes Leerzeichen auf jeder Zeile wegen einer einzigen hinzugefügten Zeile. Wer zwei nummerierte Fassungen vergleicht, weiß nun, warum jede Zeile als geändert erscheint.
Drei kleine Verhaltensweisen sollte man kennen, bevor man etwas Langes einfügt. Ein abschließender Zeilenumbruch erzeugt am Ende eine nummerierte leere Zeile, denn „a\nb\n“ an Zeilenumbrüchen zu trennen ergibt drei Teile, deren dritter leer ist — die Ausgabe endet mit „3. “. Eine leere Eingabe erzeugt „1. “ statt gar nichts. Und eine Eingabe mit Windows-Zeilenenden kommt mit Unix-Zeilenenden zurück: Das Trennen akzeptiert einen Wagenrücklauf vor dem Zeilenvorschub, das Zusammenfügen setzt nur den Zeilenvorschub zurück.
Beginn bei 1, und nur bei 1 — oder bei einer negativen Zahl
Das Feld „Beginnen bei“ gibt es, weil ein nummerierter Auszug meist irgendwo herkommt: Seite vier eines Transkripts sollte nicht wieder bei 1 anfangen. Setze es auf 500, und die Ausgabe läuft 500, 501, 502, mit Breite drei. So weit funktioniert alles wie angekündigt.
Die Null ist die Ausnahme, und das lässt sich nicht durch eine andere Schreibweise umgehen. Der Wert wird als Number(start) || 1 gelesen. Null gehört zu den falsy-Werten von JavaScript, der Ausdruck fällt also auf 1 zurück — 0 einzutippen und nichts einzutippen ergibt dasselbe. Wer eine Nummerierung im Array-Stil wollte, bei der die erste Zeile Zeile 0 ist, bekommt sie hier nicht. Ein leeres Feld verhält sich genauso, und ein Wert, der gar keine Zahl ist, ebenfalls: „abc“ ergibt 1.
Negative Startwerte funktionieren merkwürdigerweise, weil −3 truthy ist. Drei Zeilen ab −3 kommen als „-3. “, „-2. “, „-1. “ zurück — für nichts Bestimmtes nützlich, aber es zeigt, dass die Absicherung von der Falsiness handelt und nicht vom Vorzeichen. Bruchwerte werden gegen minus unendlich abgerundet: 2,7 wird 2 und −2,7 wird −3.
Der Rückweg, der nicht symmetrisch ist
remove-line-numbers hat überhaupt keine Optionen. Es wendet auf jede Zeile ein Muster an: führende Leerzeichen oder Tabs, dann die Nummer samt Markierung — Ziffern gefolgt von einem Tab, oder Ziffern in eckigen Klammern oder mit vorangestelltem Doppelkreuz, oder Ziffern gefolgt von einem Punkt, einer schließenden Klammer, einem Doppelpunkt, einer schließenden eckigen Klammer oder einem Pfeil — und danach genau ein Leerzeichen oder das Zeilenende. Alles Getroffene wird gelöscht, einmal pro Zeile. Zwei Einzelheiten dieses Satzes leisten die ganze Arbeit: Auf die Markierung muss ein Leerzeichen folgen, und verschluckt wird genau eines.
Schickt man alle elf Trennzeichen hindurch, überstehen acht die Reise: Punkt, Klammer, Doppelpunkt, Tab, „[1] “, „1] “, „#1 “ und „1 → “ kehren exakt zum Ausgangstext zurück. Drei nicht, und das Auslassen ist Absicht. „1 - alpha“, „1 | alpha“ und „1 alpha“ kommen unverändert zurück, die Nummern noch dran, denn „5 - 3 = 2“, „10 - 20 people“, „1 | Alice | 30“ und „007 James“ haben genau dieselbe Gestalt und sind weit häufiger Inhalt als Nummerierung. Ein Entferner, der diese drei rückgängig machte, fräße jedes Mal eine Tabellenzeile, wenn jemand eine einfügt.
Das Muster endete früher mit einer gierigen Folge von Leerraum und nahm die Einrückung des Textes mit; jetzt nimmt es genau ein Leerzeichen. Nummeriere fünf Zeilen JavaScript mit einer Funktion, einem if und einem return, entnummeriere sie, und die Datei kommt Byte für Byte zurück, Einrückungen inklusive. YAML und Python verhalten sich genauso, und dort zählt es am meisten: In diesen beiden Sprachen ist ein plattgedrücktes Ergebnis nicht bloß hässlich, es bedeutet nicht mehr dasselbe.
Ein Entferner kann nicht wissen, wessen Zahl das ist
Das ist die ehrliche Grenze der ganzen Idee, und die Leerzeichenregel verengt sie, statt sie aufzuheben. „1. Reis waschen“ ist eine nummerierte Zeile, wenn das Werkzeug die 1 gesetzt hat, und Inhalt, wenn die Köchin sie gesetzt hat. Nichts in der Zeichenkette unterscheidet beides, und kein Muster kann es: Die beiden Zeilen sind dieselben Bytes. Ein Leerzeichen nach dem Trennzeichen zu verlangen schließt die Unfälle aus — „3.14 is pi“ und „1.2.3 version“ kommen jetzt unberührt zurück, denn auf einen Dezimalpunkt folgt nie ein Leerzeichen — die Zufälle aber nicht. Aus „12: 30 departure“ wird weiterhin „30 departure“, aus „2026. A year.“ weiterhin „A year.“ Beides ist Zeichen für Zeichen das, was add-line-numbers schreibt; auf einer Zeile, die niemand nummeriert hat, bleibt das Datenverlust.
Zwei Dinge halten den Normalfall sicher. Die Löschung geschieht einmal pro Zeile und hält beim ersten Trennzeichen an: Eine nummerierte Preisliste englischer Schreibweise ergibt „1. 12.50 Coffee“, und beim Entnummerieren trifft das Muster „1. “ und hört auf — „12.50 Coffee“ kommt unversehrt zurück; eine Liste, die schon eigene Nummern hatte, „1. 1. alpha“, verliert genau eine Ebene. Und diese Preiszeile übersteht es jetzt sogar ohne Nummerierung, weil auf den Punkt in „12.50“ kein Leerzeichen folgt. Der Hin- und Rückweg ist damit auf jedem Text sicher, eingerückt oder flach, mit jedem der acht Trennzeichen. Zubeißen kann nur noch der Entferner allein, auf Text angewandt, den niemand nummeriert hat, und nur bei der schmalen Menge von Zeilen, die wie seine eigene Ausgabe aussehen.
Zu wissen, warum etwas sicher ist, nützt mehr als die Liste. Eine CSV mit Kennungen übersteht es — „1024, Dupont, 42“ kommt unberührt zurück — weil auf die Ziffern ein Komma folgt, und das Komma kommt in keiner der Markierungsformen vor. „100 units of flour“ und „007 James“ überstehen es, weil ein bloßes Leerzeichen ebenfalls keine ist. Dezimalzahlen und semantische Versionen sind ebenfalls sicher, aber aus dem anderen Grund: „3.14“ und „1.2.3“ tragen sehr wohl einen Punkt, und es rettet sie, dass kein Leerzeichen darauf folgt. Gefährdet ist die schmale Menge, in der eine Zahl, eine erkannte Markierung und ein Leerzeichen in dieser Reihenfolge auftreten: Jahreszahlen als Überschrift, „12: 30“ mit Leerzeichen nach dem Doppelpunkt, und — neu, seit der Markierungssatz erweitert wurde — Fußnotenzeichen wie „[1] “ und Zeilen, die mit „#1 “ beginnen.
Die Durchsicht führen, ohne etwas zu verlieren
Bewahre das unnummerierte Original dort auf, wo du es nicht überschreibst, und behandle die nummerierte Fassung wie einen Ausdruck: etwas zum Lesen, Zitieren und Kommentieren, nicht zum Bearbeiten und Zurückschicken. Jede als „Zeile 47, X durch Y ersetzen“ eingesammelte Änderung lässt sich sauber auf das Original anwenden, und die Nummern müssen nie entfernt werden.
Wenn du wirklich später entnummerieren willst, meide genau drei Trennzeichen: Strich, senkrechten Strich und einfaches Leerzeichen. Alles andere im Menü — Punkt, Klammer, Doppelpunkt, Tab, „[1] “, „1] “, „#1 “, „1 → “ — lässt sich wieder entfernen. Nimm lieber den Tab, wenn der Text in die Nähe einer Tabelle gerät: Er stellt die Nummern in eine eigene Spalte.
Code zu nummerieren, den du zurückkopieren willst, ist jetzt machbar, was es vorher nicht war: Mit Punkt, Klammer, Doppelpunkt oder Tab kommt die Datei Byte für Byte zurück, Einrückung inklusive. Der richtige Griff ist es trotzdem selten — eine Code-Durchsicht hat bessere Werkzeuge: ein Diff, einen Pull Request oder schlicht die Zeilennummern, die der Editor euch beiden längst anzeigt — aber wenn doch, nimm eines dieser vier und probiere den Hin- und Rückweg zuerst an einer Kopie.
| Eingabe | Ergebnis | Warum |
|---|---|---|
| „Beginnen bei“ auf 0, zwei Zeilen | 1. a und 2. b | Number(start) || 1 — Null ist falsy und wird zu 1 |
| „Beginnen bei“ auf −3, drei Zeilen | -3. a, -2. b, -1. c | Eine negative Zahl ist truthy, die Absicherung lässt sie durch |
| Ein Text mit 102 Zeilen, Standardtrennzeichen | „ 1. “ oben, „102. “ unten | Rechtsbündig mit Leerzeichen; die Breite ergibt sich aus der letzten Nummer |
| Text, der mit einem Zeilenumbruch endet | Eine nummerierte leere Zeile am Ende | Das Trennen an Zeilenumbrüchen ergibt ein Stück mehr, als es Textzeilen gibt |
| „1 - alpha“ durch remove-line-numbers | Unverändert | Der Strich fehlt mit Absicht: „10 - 20 people“ ist weit häufiger Inhalt als Nummerierung |
| Fünf Zeilen eingerücktes JavaScript, nummeriert und wieder entnummeriert | Der Code kommt Byte für Byte zurück, Einrückungen inklusive | Das Muster nimmt nach dem Trennzeichen genau ein Leerzeichen, keine gierige Folge |
| „3.14 is pi“, nie nummeriert, durch den Entferner | Unverändert | Auf ein Trennzeichen muss ein Leerzeichen folgen, auf einen Dezimalpunkt nie |
| „1024, Dupont, 42“, nie nummeriert, durch den Entferner | Unverändert | Das Komma kommt in keiner der acht Markierungsformen vor, also passt nichts |
| „1. 12,50 Kaffee“, vom Werkzeug nummeriert, durch den Entferner | „12,50 Kaffee“ — der Hin- und Rückweg verliert nichts | Die Ersetzung läuft einmal pro Zeile und hält beim ersten Trennzeichen an |
Häufige Fragen
- Kann ich die Nummerierung bei 0 beginnen lassen?
- Nein, und kein Trick hilft darüber hinweg. Das Werkzeug liest das Feld als Number(start) || 1. Null ist in JavaScript falsy, der Ausdruck verwirft sie also und gibt 1 zurück — 0 eintippen, das Feld leer lassen und ein Wort eintippen ergeben alle eine Liste ab 1. Geprüft mit 0, „0“, „“ und „abc“: alle vier lieferten dieselbe Ausgabe. Brauchst du eine nullbasierte Nummerierung, nummeriere ab 1 und ziehe im Kopf eins ab, oder nummeriere ab −1, wenn der Versatz wichtiger ist als das Vorzeichen: Negative Startwerte funktionieren, weil eine negative Zahl truthy ist.
- Bleiben die Nummern ausgerichtet, sobald der Text 100 Zeilen überschreitet?
- Ja. Die Breite wird aus der letzten Nummer bestimmt, bevor irgendetwas geschrieben wird, und jede Nummer wird links mit Leerzeichen auf diese Breite gebracht. Ein Text mit 102 Zeilen beginnt mit zwei führenden Leerzeichen vor Zeile 1 und keinem vor Zeile 102, sodass die Punkte eine gerade Spalte bilden. Führende Nullen gibt es nicht — du bekommst „ 7. “, nie „007. “. Eine Folge überrascht viele: Ein Text mit 99 Zeilen nutzt Breite zwei, derselbe Text mit einer Zeile mehr Breite drei, also ändert sich jede Zeile um ein Leerzeichen. Wer zwei nummerierte Fassungen mit einem Diff vergleicht, sieht deshalb die ganze Datei als geändert. Vergleiche lieber die Originale.
- Macht remove-line-numbers add-line-numbers immer rückgängig?
- Nein, aber die Gründe haben sich geändert. Es erkennt acht der elf Trennzeichen — Punkt, schließende Klammer, Doppelpunkt, Tab, „[1] “, „1] “, „#1 “ und „1 → “ — und lässt Strich, senkrechten Strich und einfaches Leerzeichen absichtlich stehen, denn „10 - 20 people“, „1 | Alice | 30“ und „007 James“ haben dieselbe Gestalt und sind meist Inhalt. Mit einem erkannten Trennzeichen ist der Hin- und Rückweg jetzt Byte für Byte gleich, Einrückung inklusive: Fünf Zeilen JavaScript mit einem um vier und acht Leerzeichen eingerückten Funktionsrumpf gingen hinein und kamen identisch zurück, ebenso YAML, Python und eine flache Preisliste.
- Ich habe den Entferner auf eine Preisliste angewandt, und er hat einen Teil davon gefressen. Was ist passiert?
- Das kann er nicht mehr. Früher löschte der Entferner führende Ziffern, auf die ein Punkt, eine schließende Klammer, ein Doppelpunkt oder ein Tab folgte, ohne dahinter etwas zu verlangen — so wurde aus „3.14 is pi“ das Ergebnis „14 is pi“ und aus „12.50 Coffee“ das Ergebnis „50 Coffee“. Das Muster verlangt jetzt nach dem Trennzeichen ein Leerzeichen oder das Zeilenende, und auf einen Dezimalpunkt folgt nie ein Leerzeichen: „3.14 is pi“, „1.2.3 version“ und „12.50 Coffee“ kommen alle unberührt zurück. Mitnehmen kann er noch eine Zeile, die genau die Gestalt seiner eigenen Ausgabe hat — „2026. A year.“ ergibt „A year.“, „12: 30 departure“ ergibt „30 departure“ — und, seit der Markierungssatz erweitert wurde, Fußnotenzeichen: „[1] See note“ ergibt „See note“. Eine kommagetrennte Liste ist ohnehin sicher, denn das Komma kommt in keiner Markierungsform vor.
- Sollte ich Quellcode für ein Code-Review nummerieren?
- Meist nicht, riskant ist es aber nicht mehr. Code trägt überall dort, wo er gelesen wird, bereits Zeilennummern — im Rand des Editors, in einem Diff, in der Review-Oberfläche jeder Plattform — Nummerieren fügt also vor allem Rauschen hinzu. Den Rückweg übersteht er inzwischen: Mit Punkt, Klammer, Doppelpunkt oder Tab kommt eine nummerierte und wieder entnummerierte eingerückte Datei Byte für Byte zurück, Einrückung inklusive — früher nicht. Drei Trennzeichen werden weiterhin nie entfernt — Strich, senkrechter Strich und einfaches Leerzeichen —, meide sie also, wenn die Nummern wieder weg sollen. Nummerieren lohnt sich bei Text ohne eigene Nummern, der außerhalb eines Werkzeugs gelesen wird, das welche liefert: ein als Dokument verschickter Vertrag, eine in einem Chat besprochene Untertiteldatei, eine an eine Übersetzerin geschickte Liste von Zeichenketten. Prüfst du Code und die Plattform ist unerreichbar, bleibt es ruhiger, ihn in einem Block zu zitieren und nach der Funktion statt nach der Zeile zu benennen.
Artikel, die dich interessieren könnten
Alle Ratgeber →Ähnliche Tools
Alles hier beschreibt, was diese vier Werkzeuge heute tun — geprüft, indem ihr eigener Code mit genau den in jedem Artikel abgedruckten Eingaben ausgeführt wurde — und nicht, was ein Standard ihnen vorschreibt. Wo ein Werkzeug einen Fall falsch behandelt, steht das klar da, statt umgangen zu werden, und nichts wurde geändert, damit ein Artikel sich besser liest. Zwei Folgerungen. Lass jede Umwandlung zuerst über eine Kopie laufen und vergleiche beide Enden: Ein Textwerkzeug, das etwas löscht, sagt es nicht. Und betrachte ein Geheimnis als geteilt, sobald es die Seite verlässt — es in einen Chat, ein Ticket oder ein Repository einzufügen verbrennt es, so gut es auch erzeugt wurde.
Quellen
Hast du einen Fehler in diesem Artikel entdeckt?