How to convert YYYYMMDDHHMMSS to a date readable by `date`
Solution 1
date doesn't allow "YYYYMMDDHHMMSS", but it does "YYYYMMDD HH:MM:SS", so:
D="20100101123456"
date -d "${D:0:8} ${D:8:2}:${D:10:2}:${D:12:2}"
Solution 2
If the format is totally fixed, you could just do it within bash, chopping up the string:
d=20100101123456
pretty_date="${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:${d:10:2}:${d:12:2}"
# 2010-01-01 12:34:56
...
I wouldn't bother trying to use regex - like you said, the pattern gets ugly fast. A lot of repetition of ([0-9]{4})
, even with extended or perl regex. Or you could be flexible and just match .
; no verification.
Solution 3
What's with all of these regular expression answers? The date(1) tool has the ability to use strftime() style date formatting... an an example of converting one date type to another:
$ date -j -f "%Y%m%d%H%M%S" "20100101123456" "+%Y-%m-%d %H:%M:%S"
2010-01-01 12:34:56
So if it's not in the format you want, convert it like that and then use it. If you just want to set it, you can simply do:
$ date -f "%Y%m%d%H%M%S" "20100101123456"
Solution 4
Try this:
echo "20101106213245" | sed -r 's/^.{8}/& /;:a; s/([ :])(..)\B/\1\2:/;ta'
Result:
20101106 21:32:45
- Insert a space after the eighth character
- [label a] After a space or colon and the next two characters, add a colon
- If a replacement was made, goto label a
You want some hyphens, too?
echo "20101106213245" | sed -r 's/^.{4}/&-/;:a; s/([-:])(..)\B/\1\2:/;ta;s/:/-/;s/:/ /'
Result:
2010-11-06 21:32:45
- Insert a hyphen after the fourth character
- [label a] After a hyphen or colon and the next two characters, add a colon
- If a replacement was made, goto label a
- Change the first colon to a hyphen (
2010-11:06:21:32:45
->2010-11-06:21:32:45
) - Change the next colon to a space (
2010-11-06:21:32:45
->2010-11-06 21:32:45
)
Solution 5
sed -ne 's/\(....\)\(..\)\(..\)\(..\)\(..\)\(..\)/\1-\2-\3 \4:\5:\6/p'
I admit it'S a mouthful. All the .'s should optimally be [0-9] or \d, though I don't remember if sed supports the latter.
Sousou
Updated on June 14, 2022Comments
-
Sousou almost 2 years
I have a set of date/time strings in the YYYYMMDDHHMMSS format that I want to convert to something readable by the
date
utility. Usually, I can do something like:date -d "2010-10-01 12:34:56"
However,
date
does not like the YYYYMMDDHHMMSS:date -d "20100101123456"
..invalid dateSo, I probably need to refine the string to be in the prior format. I'm thinking
sed
is the answer, but it gets ugly very fast. I'm quite certain my strings will be the proper format, so how do I easily convert them? -
SourceSeeker over 13 yearsThat's valid for BSD, but not for GNU.
-
uzi over 13 yearsSo you're right... a rare instance where the GNU tool is inferior.
-
Sousou over 13 yearsThe other instance of inferiority is the license terms. :)
-
Mark Stinson over 11 yearsIn shell formatting saves significant time and eliminates the overhead load of pipes and external binaries. There's lots of ${} transformations available. And do not forget use [[ ]] so tests are also ran in the same space.
-
tripleee about 6 yearsGenerally
sed
does not support Perl shorthands like\d
,\s
,\t
, etc but you can sayd='[0-9]'; sed -ne "s/\\($d$d$d$d\\)\\($d$d\\)\\($d$d\\)\\($d$d\\)\\($d$d\\)\\($d$d\\)"'/\1-\2-\3 \4:\5:\6/p'
(though notice how the double quotes force the backslashes to require doubling; you can't use single quotes because then the shell would not expand the value of$d
). -
Cadoiz over 2 yearstbh I find this more readable then this one, +1
-
Cadoiz over 2 yearsBe aware that reading a date (see
-d
-Option) is not a part of POSIX date. But as long as you're not working on distributions like Solaris (OP has tagged it linux and not unix) you should be good. :) See my answer here for a bit more details.