
Nehmen wir an, ich habe eine Datei mit folgendem Inhalt:
Dies ist eine _Datei_, die einige _spezielle_ Schlüsselwörter enthält, die ich _gerne_ ersetzen möchte.
Ich kann die speziellen Schlüsselwörter mit „%s/_*_/irgendwas“ suchen und ersetzen, aber ich möchte, dass „irgendwas“ die Ausgabe eines externen Befehls ist. Ist das in vim möglich oder muss ich es mit awk ausführen?
Antwort1
Ja, das können Sie. Siehe :help sub-replace-special
; das \=
ermöglicht Ihnen, durch einen Vim-Ausdruck zu ersetzen. Und system()
kann einen externen Befehl ausführen und dessen Ausgabe zurückgeben. Siehe mein triviales Beispiel mit hostname
. Beachten Sie, dass ich verwenden musste, substitute()
um die nachfolgenden Zeilenumbruchzeichen in der Ausgabe zu entfernen.
:%s/_[^_]*_/\=substitute(system('hostname'),'\n','','g')/g
PS: Ich habe auch Ihr Regexp-Muster korrigiert, damit es zu Ihrem Beispiel passt.
Antwort2
In Ingos Antwort, die mir sehr geholfen hat, sehe ich nicht, wie ich auf ein Untermuster der Übereinstimmung verweisen und es als Argument für den Shell-Befehl verwenden kann („erzeugt durch einen Konsolenbefehl mit dem Ausdruck als Argument“).
In meinem Fall hatte ich Protokollzeilen folgender Form: [<unix timestamp>] <message>
, d. h. [1406844000] foobar
. Ich wollte ihnen die Zeit in einer für Menschen lesbaren Form voranstellen.
Der folgende Vim-Befehl gleicht den Zeitstempel (Teilübereinstimmung 1) und die Nachricht (den Rest, Teilübereinstimmung 2) ab und stellt die Zeitzeichenfolge dem Datumsbefehl voran:
:% s/^\[\(\d\+\)\] \(.*\)$/\=substitute(system('date -d @'.submatch(1)),'\n', '', 'g').': ['.submatch(1).'] '.submatch(2)/
[1406844000] foobar
bekommt Fr 1. Aug 00:00:00 CEST 2014: [1406844000] foobar
.
HTH
Antwort3
Für die Base64-Ersetzung in einer LDIFF-Datei:
:%s/:: \(.*\)$/\=substitute(': ' . system('echo '.submatch(1).'|base64 -d'),'\n','','g')/