Ich habe eine Anzahl von Zeilen in einer Datei, und ich möchte jede Zeile 11 Mal kopieren (jede Zeile in 12 Zeilen umwandeln) und die letzte "1" in jeder Zeile erhöhen, sodass die 12 Zeilen "1" bis "haben". 12 ", wo die" 1 "ursprünglich war. Es kann andere Vorkommen von "1" in jeder Zeile geben, aber die "1", die ich erhöhen möchte, ist immer das letzte Vorkommen in jeder Zeile. Eine andere Sichtweise ist, dass die letzte "1" immer nach "/ nt /" steht - wie in "/ nt / 1" (und es wird immer das einzige Vorkommen von "/ nt / 1" in jeder Zeile sein) .
Also zum Beispiel, wenn ich habe:
1stlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/1blah
3rdlineblahblahblah/nt/1blah
Ich möchte daraus machen:
1stlineblahblahblah/nt/1blah
1stlineblahblahblah/nt/2blah
1stlineblahblahblah/nt/3blah
1stlineblahblahblah/nt/4blah
1stlineblahblahblah/nt/5blah
1stlineblahblahblah/nt/6blah
1stlineblahblahblah/nt/7blah
1stlineblahblahblah/nt/8blah
1stlineblahblahblah/nt/9blah
1stlineblahblahblah/nt/10blah
1stlineblahblahblah/nt/11blah
1stlineblahblahblah/nt/12blah
2ndlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/3blah
...
Ich hatte zuvor den Befehl gefunden:
:for i in range(0,12) | put ='1stlineblahblahblah/nt/'.i.'blah' | endfor
funktioniert für diesen Zweck, aber ich müsste diesen Befehl für jede Zeile manuell ausführen und jede Zeile selbst eingeben (oder kopieren und einfügen). Gibt es eine Möglichkeit, die bereits in der Datei enthaltenen Zeilen zu übernehmen und nur einen Befehl auszuführen, der jede Zeile in die von mir beschriebene Weise in zwölf Zeilen umwandelt?
Vielen Dank im Voraus an alle, die mir dabei helfen können. Ich wollte auch nur erwähnen, dass dies meine zweite Frage hier ist, und ich war erfreut, mehrere schnelle und effektive Lösungen für meine erste Frage erhalten zu haben, für die ich sehr dankbar war.
quelle
Sie könnten dies tun, indem Sie
global
Befehl ex, um das Makro n- mal für jede Zeile in der Datei auszuführen .Machen Sie nach dem Aufzeichnen des Makros die während der Aufnahme vorgenommenen Änderungen rückgängig. Andernfalls werden n + 1 zusätzliche Zeilen für die erste Zeile und n für aufeinanderfolgende Zeilen angezeigt.
Zeichnen Sie das Makro mit in das
a
Register einDies zeichnet den folgenden Befehl in register
a
(qa...q
) auf:yyp
: Dupliziere die aktuelle Zeile$
: zum Zeilenende gehen?\d<CR>
: Suche rückwärts nach einer einzelnen Ziffer<C-A>
: Inkrementiere die Ziffer unter dem Cursor um einsWenn das Makro aufgezeichnet wird, entfernen Sie die während der Aufzeichnung vorgenommenen Änderungen, indem Sie entweder (
uu
) rückgängig machen oder die aktuelle Zeile (dd
) löschen . Wiederholen Sie dann das Makro11
(oder eine beliebige Anzahl von Malen) für jede Zeile in der Datei mit dem globalen Befehl:quelle
Zwei Wege:
Verwenden Sie ein Makro!
Beginnen mit
Mit dem Cursor in der ersten Zeile
Welches tut:
qq
Starten Sie die Aufnahme eines Makros in das q-Registeryyp
Ziehen Sie die aktuelle Zeile und fügen Sie sie unten ein$?\d<CR>
Gehen Sie zum Ende der Zeile und suchen Sie die erste Ziffer, die nach hinten schaut<Ctrl-a>
Erhöhen Sie die Anzahlq
Beenden Sie die Aufnahme des Makros.Dies lässt Sie mit:
Mit dem Cursor in der zweiten Zeile. Wiederholen Sie dieses Makro einfach so oft wie gewünscht (wiederholen Sie es beispielsweise zehnmal mit 10 @ q). Wenn Sie diesen Prozess für jede Zeile automatisieren möchten, führen Sie ihn global für jede Zeile aus:
:g//normal 11@q
Alternativ mit einer neueren Version von vim: Fügen Sie die gewünschte Zeile beliebig oft ein, wählen Sie mit dem visuellen Block die Ziffer aus, die Sie erhöhen möchten, und drücken Sie
g <Ctrl-a>
. Dies sollte alle Zahlen im visuellen Block nach Ihren Wünschen erhöhen. Dies ist jedoch ein manueller Prozess.quelle
g <c-a>
Weg. Danke für das Teilen.Ich finde es am einfachsten, Makros für solche One-Shot-Aufgaben zu verwenden. Beginnen Sie einfach mit der Aufnahme eines Makros mit dem
q
Namen + des Registers und führen Sie die Aufgabe einmal aus. Ich sehe hier eine wiederholbare Aufgabe:Zeichnen Sie nun
a
im normalen Modus die erforderlichen Tastenanschläge zur Registrierung auf:Löschen Sie die Zeile erneut, um zu testen, ob die elfmalige Ausführung des Makros das richtige Ergebnis für eine Zeile ergibt:
Es tut! Lassen Sie uns also erneut rückgängig machen und den gesamten Prozess in einem zweiten Makro automatisieren
b
:Jetzt können Sie
@b
bis zum Ende der Datei ausführen und es sollte die gewünschte Ausgabe erzeugen. Es klingt kompliziert, ist es aber nicht, wenn Sie erst einmal an die typischen Bearbeitungsmuster gewöhnt sind.quelle
qaVyp$b<c-a>
. Oder besser einfachqayyp$b<c-a>
.qqyyp$?\d<CR><Ctrl-a>q
von @fruglemonkey und @jjaderberg ist besser, da es die letzte Nummer sucht. Ich werde es der Vollständigkeit halber ändern.Speichern Sie das folgende Makro und verwenden Sie es für jede Zeile:
Der Hauptunterschied zu den anderen Antworten besteht darin, dass
g<C-a>
eine Spaltenauswahl verwendet wird, die jede Zeile mit einer anderen Nummer erhöht. Überprüfen Sie:help v_g_CTRL-A
für weitere Informationen. Ich habe auch verwendet\zs
, um die Startposition des Musters so auszuwählen, dass der Cursor bei der Nummer nach der Suche stoppt.Bitte beachten Sie, dass Sie eine aktuelle Version von Vim benötigen, damit dies funktioniert.
quelle
g<C-a>
@fruglemonkey und Sie Bezug genommen haben, aber danke, dass Sie geantwortet haben. Ich sollte beachten, dass beim Ausprobieren Ihres Makros - kurz bevor ich zumg<C-a>
Teil komme - nicht das letzte "1" -Zeichen, das ich inkrementieren möchte, blockiert wird, sondern das Zeichen vor dem ersten "1" "Zeichen, das blockmarkiert wird. (Auch ich denke, es wäreyy11p
und10j
im Makro, da ich 11 Zeilen hinzufügen möchte - für insgesamt 12.)\zs
, aber ich könnte genauso gut einfach eine hinzugefügt habenl
nach<CR>
.vim -u NONE
. Ich habe das gerade gemacht und das funktioniert perfekt! Tatsächlich würde die Suche auf keinen Fall mit der ersten 1 übereinstimmen, da ein vorhergehender Schrägstrich erforderlich ist.