Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

let's say I have a file with the following content:

This is a _file_ which has some _special_ keywords, that I would _like_ to replace.

I can do a search and replace of the speical keywords with "%s/_*_/something", but I would like "something" to be an output of an external command. Is this possible in vim, or do I need to awk it?

share|improve this question

2 Answers 2

up vote 5 down vote accepted

Yes, you can. See :help sub-replace-special; the \= allows you to replace with a Vim expression. And system() can execute an external command and return its output. See my trivial example with hostname. Note that I had to use substitute() to get rid of the trailing newline character(s) in the output.

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

PS: I also corrected your regexp pattern to match your example.

share|improve this answer

In Ingos answer, which helped me a lot, I don't see how to reference a subpattern of the match and use it as an argument to the shell command ("produced by a console command with the expression as its argument").

In my case I had log lines of the following form: [<unix timestamp>] <message>, i.e. [1406844000] foobar. I wanted to prepend them with the time in a human readable form.

The following vim command matches the timestamp (submatch 1) and the message (the rest, submatch 2) and prepends the time string from date command:

:% s/^\[\(\d\+\)\] \(.*\)$/\=substitute(system('date -d @'.submatch(1)),'\n', '', 'g').': ['.submatch(1).'] '.submatch(2)/

[1406844000] foobar gets Fr 1. Aug 00:00:00 CEST 2014: [1406844000] foobar.

HTH

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.