Reputation: 1467
My Data looks like this (2 record(s) from the file which is open in vi-editor) -
445544|2016-02-09|026|111|W108576|1|2015-02-13|2017-02-17|WHI|2016-02-10|SC|RN
114433|2016-02-07|046|366|WR71X253|4|2016-02-09|2017-02-17|GE|2016-02-08|SC|RN
I want to change the date format of the last date value from YYYY-mm-dd to mm-dd-YYYY i.e.
'2016-02-10' to '02-10-2016' &
'2016-02-08' to '02-08-2016'
Following is what I have tried
^.*\(\<[0-9]{4}\>\)-\(\<[0-9]{2}\>\)-\(\<[0-9\]{2}\>\)|\w\+|\w\+\n$
It says - E486: Pattern not found:
I know that once I will have the find pattern I can do -
:STARTLINE,ENDLINEs/<PATTERN to find>/<PATTERN to replace>/g
Please help ?
Upvotes: 0
Views: 2862
Reputation: 59297
The shortest regex solution is to use \zs
, \v
or very magic if you
have it enabled by default, and to take advantage of greediness. If
you match a .*
, everything is matched. The engine then goes back
step by step trying to match what's left to match. This way the date
will be the last date present in the line, aways.
s/\v.*\zs(\d{4})-(\d\d-\d\d)/\2-\1
Upvotes: 1
Reputation: 406
%s/\(.*\|\)\(\d\{4\}\)-\(\d\{2\}\)-\(\d\{2\}\)/\1\3-\4-\2/g
\(.*\|\)
greedily match everything up to the last |
that also satisifies\(\d\{4\}\)-\(\d\{2\}\)-\(\d\{2\}\)
match YYYY-MM-DDUpvotes: 2
Reputation: 195199
You can change a single line by pressing this in normal mode:
$2T-Xdbf|i-<c-r>"<esc>
If you want to know what is happened, just press those keys, and see what is changed in your buffer.
To apply it to all lines:
btw, in vimgolf, macro will usually beat :cmd
:-)
qq$2T-Xdbf|i-<c-r>"<esc>+@qq
then press @q
Note, since I used nested macro, pls do a qqq
before recording macro, so that the old stuff in q
is cleared.
You can wrap those normal command into :norm
too:
:%norm! $2T-Xdbf|i-^R"^[
Note,
^R
you press ctrl-v ctrl-r
^[
you press ctrl-v ESC
Upvotes: 2
Reputation: 23677
s/\v^([^|]+\|){9}\zs(\d{4})-(\d{2}-\d{2})/\3-\2/
\v
very magic, avoids too many \
s^([^|]+\|){9}\zs
from start of line, 9 columns delimited by |
. By using \zs
, regex following it will be start of match for replacement(\d{4})-(\d{2}-\d{2})
capture YYYY and MM-DD as two groups\3-\2
re-arrange as neededWithout \zs
s/\v^(([^|]+\|){9})(\d{4})-(\d{2}-\d{2})/\1\4-\3/
Upvotes: 2