
Допустим, у меня есть файл со следующим содержимым:
Это _файл_, содержащий некоторые _специальные_ ключевые слова, которые я _хотел бы_ заменить.
Я могу выполнить поиск и замену специальных ключевых слов с помощью "%s/_*_/something", но я хотел бы, чтобы "something" было выводом внешней команды. Возможно ли это в vim, или мне нужно использовать awk?
решение1
Да, можно. Смотрите :help sub-replace-special
; \=
позволяет вам заменить выражением Vim. И system()
может выполнить внешнюю команду и вернуть ее вывод. Смотрите мой тривиальный пример с hostname
. Обратите внимание, что мне пришлось использовать substitute()
, чтобы избавиться от завершающего символа(ов) новой строки в выводе.
:%s/_[^_]*_/\=substitute(system('hostname'),'\n','','g')/g
PS: Я также исправил ваш шаблон регулярного выражения, чтобы он соответствовал вашему примеру.
решение2
В ответе Инго, который мне очень помог, я не вижу, как сослаться на подшаблон соответствия и использовать его в качестве аргумента команды оболочки («создается консольной командой с выражением в качестве аргумента»).
В моем случае у меня были строки журнала следующего вида: [<unix timestamp>] <message>
, т. е [1406844000] foobar
. Я хотел предварить их временем в удобной для чтения форме.
Следующая команда vim сопоставляет временную метку (submatch 1) и сообщение (остальное, submatch 2) и добавляет строку времени из команды date:
:% s/^\[\(\d\+\)\] \(.*\)$/\=substitute(system('date -d @'.submatch(1)),'\n', '', 'g').': ['.submatch(1).'] '.submatch(2)/
[1406844000] foobar
получает Fr 1. Aug 00:00:00 CEST 2014: [1406844000] foobar
.
НТН
решение3
Для подстановки base64 в файле ldiff:
:%s/:: \(.*\)$/\=substitute(': ' . system('echo '.submatch(1).'|base64 -d'),'\n','','g')/