In vim
, you could do:
:%s/\v^\d{4}(-\d{2}){2} \d{2}(:\d{2}){2}.*/&\r
Note the \v
for very magic so you don't need to add backslashes before every {}()
.
Yes, \r
in the replacement adds a newline (splits the line in two using the wording at :help s/\r
), not a carriage return as one might have expected.
In standard vi
(\d
, \v
, \r
, norm
being all vim
extensions), the equivalent would look like:
:%s/^[[:digit:]]\{4\}\(-[[:digit:]]\{2\}\)\{2\} [[:digit:]]\{2\}\(:[[:digit:]]\{2\}\)\{2\}.*/&^M/
Where the ^M
is entered by pressing Ctrl+V followed by Enter (and again inserts a LF aka newline aka ^J
, not CR aka carriage-return aka ^M
).
But the vi
implementation on CentOS is vim
(and has been since at least as far back as CentOS 4) so you should be able to rely on the vim
extensions in vi
there.
In any case tr
is a tool to transliterate, replace characters with other characters or delete or squeeze them, it cannot be used here.
sed
, awk
or perl
could be used (AFAIK, \d
as a regex operator originated in perl):
perl -pi -e '$_ .= "\n" if /^\d{4}(-\d{2}){2} \d{2}(:\d{2}){2}/' your-file
To edit the file i
n place. Or:
perl -p -e '$_ .= "\n" if /^\d{4}(-\d{2}){2} \d{2}(:\d{2}){2}/' < your-file > new-file
To get the result into a new file.
Or here, provided the Regex::Common::time
module is available:
perl -MRegexp::Common=time -p -e '
$_ .= "\n" if m{^$RE{time}{strftime}{-pat=>"%Y-%m-%d %H:%M:%S"}}
' < your-file > new-file
Which will do a stricter matching (not match on 2023-13-00 25:61:62
for instance). There's also a $RE{time}{iso}
which will match those dates, but also many other variants of ISO8601 dates including some without date or time component, so can't be used here.
You can see the actual regex with:
$ perl -MRegexp::Common=time -le 'print $RE{time}{strftime}{-pat=>"%Y-%m-%d %H:%M:%S"}'
(?:(?:\d{4})-(?:(?:(?=[01])(?:0[1-9]|1[012])))-(?:(?:(?=[0123])(?:0[1-9]|[12]\d|3[01]))) (?:(?:(?=[012])(?:[01]\d|2[0123]))):(?:(?:[0-5]\d)):(?:(?:(?=[0-6])(?:[0-5]\d|6[01]))))