Ich habe mir diese Frage angesehen und mich dann gefragt, wie ich meine Antwortsed
implementieren könnte, die
nur
POSIX verwendet
ex
.
Der Trick ist, dass sed
ich zwar den Haltebereich mit dem Musterbereich vergleichen kann, um festzustellen, ob sie genau gleichwertig sind (mit
G;/^\(.*\)\n\1$/{do something}
), aber keine Möglichkeit kenne, einen solchen Test durchzuführen ex
.
Ich weiß, dass ich in Vim Y
die erste Zeile
ankeln und dann eingeben könnte, :2,$g/<C-r>0/d
um fast das zu tun, was ich spezifiziere - aber wenn die erste Zeile alles andere als sehr einfachen alphanumerischen Text enthält, wird dies in der Tat zu einem Zufall, da die Zeile als
Regex eingefügt wird , nicht nur eine Zeichenfolge zum Vergleich. (Und wenn die erste Zeile einen Schrägstrich enthält, wird der Rest der Zeile als Befehl interpretiert!)
Wenn ich also alle Zeilen löschen möchte myfile
, die mit der ersten Zeile identisch sind - aber nicht die erste Zeile löschen -, wie kann ich das verwenden ex
? Wie könnte ich das überhaupt tun vi
?
Gibt es eine POSIX-Möglichkeit, eine Zeile zu löschen, wenn sie genau mit einer anderen Zeile übereinstimmt?
Vielleicht so etwas wie diese imaginäre Syntax:
:2,$g/**lines equal to "0**/d
<C-r>0
sehr gut. Ich bin mir nicht sicher, ob Sie nur mit Ex-Befehlen besser abschneiden können, da Sie Sonderzeichen schützen müssen. Ohne die POSIX-konforme Einschränkung würden Sie wahrscheinlich den sehr nomagischen Schalter verwenden \V
und dann den Backslash (da er auch \V
mit dieser escape()
Funktion seine besondere Bedeutung behält ) mit der Funktion schützen, deren zweites Argument eine Zeichenfolge ist, die alle Zeichen enthält, die Sie maskieren möchten .
:execute '2,$g/\V' . escape(getline(1), '\/') . '/d'
Oder Sie könnten ein anderes Zeichen für das Mustertrennzeichen wie ein Semikolon verwenden. In diesem Fall müssten Sie keinen Schrägstrich im Muster schützen. Es würde so etwas wie geben::execute '2,$g;\V' . escape(getline(1), '\') . ';d'
sed
auch sehr gut. Mit Vim delegieren Sie häufig bestimmte spezielle Aufgaben an andere Programme und sed
sind wahrscheinlich ein gutes Beispiel dafür. Übrigens müssen Sie nicht sed
auf Ihrem gesamten Puffer laufen . Wenn Sie es nur für einen Teil des Puffers ausführen möchten, können Sie einen Bereich angeben. Wenn Sie beispielsweise nur die Zeilen zwischen 50 und 100 filtern möchten, können Sie Folgendes eingeben : :50,100!<your sed command>
.
:execute '2,$g/\V' . escape(getline(1), '\') . '/d'