将 vim 中的正则表达式替换为以表达式为参数的控制台命令生成的输出?

将 vim 中的正则表达式替换为以表达式为参数的控制台命令生成的输出?

假设我有一个包含以下内容的文件:

这是一个包含一些特殊关键字的文件,我希望能替换它们。

我可以用“%s/_*_/something”搜索并替换特殊关键字,但我希望“something”是外部命令的输出。这在 vim 中可行吗,还是我需要 awk 来实现?

答案1

是的,你可以。请参阅:help sub-replace-special\=允许你用 Vim 表达式替换。并且system()可以执行外部命令并返回其输出。请参阅我使用 的简单示例hostname。请注意,我必须使用substitute()来删除输出中的尾随换行符。

:%s/_[^_]*_/\=substitute(system('hostname'),'\n','','g')/g

PS:我还修正了你的正则表达式模式以匹配你的例子。

答案2

在对我帮助很大的 Ingos 的回答中,我没有看到如何引用匹配的子模式并将其用作 shell 命令的参数(“由以表达式为参数的控制台命令生成”)。

在我的例子中,我有以下形式的日志行:[<unix timestamp>] <message>,即[1406844000] foobar。我想以一种人类可读的形式在它们前面加上时间。

以下 vim 命令匹配时间戳(子匹配 1)和消息(其余,子匹配 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

对于 ldiff 文件中的 base64 替换:

:%s/:: \(.*\)$/\=substitute(': ' . system('echo '.submatch(1).'|base64 -d'),'\n','','g')/

相关内容