Einen regulären Ausdruck in vim durch eine Ausgabe ersetzen, die von einem Konsolenbefehl mit dem Ausdruck als Argument erzeugt wird?

Einen regulären Ausdruck in vim durch eine Ausgabe ersetzen, die von einem Konsolenbefehl mit dem Ausdruck als Argument erzeugt wird?

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] foobarbekommt 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')/

verwandte Informationen