With milliseconds; before:


I want to get:


Another example: from


I want to get this:


1 Answer 1

:%s#\d\+\ze\.#\=system('printf "%02d:%02d:%02d" $(('.submatch(0).'/3600)) $(('.submatch(0).'%3600/60)) $(('.submatch(0).'%60))')#g

\d\+ mean one or more digits.

\ze mean the end of search pattern, \. after that is analog of look-forward for the dot.

Also here we use # as an alternative delimiter - because we already use / for division.

\= in the replace part mean that we will use sub-replace-expression.

:h sub-replace-expression is copied below:

Substitute with an expression           *sub-replace-expression*
When the substitute string starts with "\=" the remainder is interpreted as an
expression.  This does not work recursively: a substitute() function inside
the expression cannot use "\=" for the substitute string.

The special meaning for characters as mentioned at |sub-replace-special| does
not apply except for "<CR>", "\<CR>" and "\\".  Thus in the result of the
expression you need to use two backslashes to get one, put a backslash before a
<CR> you want to insert, and use a <CR> without a backslash where you want to
break the line.

For convenience a <NL> character is also used as a line break.  Prepend a
backslash to get a real <NL> character (which will be a NUL in the file).

When the result is a |List| then the items are joined with separating line
breaks.  Thus each item becomes a line, except that they can contain line
breaks themselves.

The whole matched text can be accessed with "submatch(0)".  The text matched
with the first pair of () with "submatch(1)".  Likewise for further
sub-matches in ().

printf syntax: 02d mean two digits: in will add leading zero when one digit.

%60 mean reminder after division to 60.

See good article Find, convert and replace dates with Vim substitutions.

  • For ffmpeg for cutting silence without reencoding: for decreasing of milliseconds against sound artefact: :%s#inpoint .*\zs\d\+#\=submatch(0)-1#g Commented Nov 12, 2018 at 12:20
  • Again for the case of ffmpeg about preparing file for silence cut: if you need to increase number of digits in milliseconds for safer/simpler decrease: :%s#\.\d$#\=submatch(0).'0'# Commented Nov 12, 2018 at 13:16
  • 2
    Why shell out with system()? Vim can do math and has its own printf().
    – jamessan
    Commented Nov 12, 2018 at 13:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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