Ich möchte Linien nur für Linien zusammenfügen, die ein bestimmtes Muster haben (z. B. ;
), aber wenn g/;/j
sie verwendet werden, funktionieren sie nicht wie erwartet, es sei denn, sie werden mehrmals aufgerufen.
Zum Beispiel den folgenden Inhalt:
a
1;
2;
3;
4;
5;
b
6;
7;
8;
9;
c
bei Verwendung von: :g/;/j
die Ausgabe ist:
a
1; 2;
3; 4;
5; b
6; 7;
8; 9;
c
oder :g/;/-j
gibt:
a 1; 2; 3; 4; 5;
b 6; 7; 8; 9;
c
ähnlich mit : :g/;\_.\{-};/j
.
Meine erwartete Ausgabe ist:
a
1; 2; 3; 4; 5;
b
6; 7; 8; 9;
c
oder ähnliches, so dass alle Linien, die das Muster enthalten, miteinander verbunden werden.
Wie kann dies erreicht werden?
global-command
Kenorb
quelle
quelle
:g/;/j
funktioniert nicht, da dies in zwei Durchgängen erfolgt: Zuerst wird der Puffer gescannt, dann wird der Befehl auf die übereinstimmenden Zeilen angewendet.Antworten:
Mögliche Erklärung des Problems
Ich denke, der Grund, warum
:g/;/j
nicht funktioniert, ist, dass der:g
Befehl mit einem 2-Pass-Algorithmus arbeitet:;
:g
Verbindet die Linie während des zweiten Durchgangs mit der Linie1;
,2;
da1;
sie während des ersten Durchgangs markiert wurde. Ich vermute jedoch (nicht sicher), dass es nicht1; 2;
mit verbunden ist,3;
da die Zeile2;
nicht mehr existiert. Ihr Inhalt wurde mit der1;
bereits verarbeiteten Zeile zusammengeführt .So
:g
sieht für die nächste Zeile , die während der ersten Durchlauf markiert wurde (3;
) und verbindet es mit dem folgenden (4;
). Danach das Problem wiederholt, ist es nicht beitreten kann3; 4;
mit ,5;
weil die Leitung4;
nicht mehr existiert.Lösung 1 (mit Vimscript)
Vielleicht können Sie eine Funktion aufrufen, wenn eine Zeile mit
;
gefunden wird, um zu überprüfen, ob die vorherige Zeile auch ein Semikolon enthält:Verwenden Sie dann den folgenden globalen Befehl:
Oder ohne Funktion:
Lösung 2 (ohne Vimscript)
Immer wenn der globale Befehl
:g
das Muster findet;
, führt er den Befehl aus:.,/^[^;]*$/-1j
Es kann so aufgeschlüsselt werden:
Wo :
b
kann so weiter aufgeschlüsselt werden:j
ist die abgekürzte Form des Ex-Befehls,:join
der wie die meisten anderen Ex-Befehle ein Bereich vorangestellt werden kann.Hier wird es von dem Bereich voran:
.,/^[^;]*$/-1
(a,b
)ein Bereich folgt die Form ,
a,b
woa
und imb
Allgemeinen 2 Zeilennummern sind, und ermöglicht es auf einer Gruppe von Zeilen , deren Zahl zu betreiben ist zwischena
undb
, statt nur einem.Der
j
Befehl verbindet also alle Zeilen zwischen dem aktuellen (a
) und dem nächsten, die kein Semikolon minus eins (b
) enthalten.Weitere Informationen finden Sie unter:
quelle
Ich mache die ganze Zeit einen ähnlichen Beitritt mit einer globalen Suche und ersetze:
\n
entspricht newline.So finden und löschen Sie Leerzeilen:
Ich bin nicht sicher warum, aber wenn Sie eine neue Zeile einfügen möchten, müssen Sie verwenden
\r
quelle
s
allein wird nur für eine Zeile funktionieren, um es global zu machen, müssen Sie verwenden%s
, aber dann wird es fast alle Zeilen verbinden, einschließlich Nicht-;
Zeilen:s
Befehl genau für das verwenden, was Sie wollen. Ich denke, das%s/;\n\(.*;\)\@=/;/
macht was du brauchst.