nitinr708
nitinr708

Reputation: 1467

In Vi-editor How do I find and change date format of a specific date?

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

Answers (4)

sidyll
sidyll

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

Steven
Steven

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-DD

Upvotes: 2

Kent
Kent

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:

Marco

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.

Normal command

You can wrap those normal command into :norm too:

:%norm! $2T-Xdbf|i-^R"^[

Note,

  • above ^R you press ctrl-v ctrl-r
  • the ^[ you press ctrl-v ESC

Upvotes: 2

Sundeep
Sundeep

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 needed

Without \zs

s/\v^(([^|]+\|){9})(\d{4})-(\d{2}-\d{2})/\1\4-\3/

Upvotes: 2

Related Questions