1

Given a date in format 20130522, I need to generate a sequence of date+hour as below:

2013052112,2013052113,2013052114,...,2013052122,2013052123, 2013052200,2013052201,2013052202,...,2013052222,2013052223, 2013052300 

in which the first date+hour is 12 hours before the given date and the last date+hour is the midnight in the next day of the given date.

I tried several ways but none of them is ideal. How to generate such a sequence in a clean way using shell script? Thanks!

--Edit--

Per your request, this is what I have so far:

day=20130522 begin=`date --date "$day -12 hours"` begin=`date -d "${begin:0:8} ${begin:8:2}" +%s` end=`date --date "$day +1 day"` end=`date -d "${end:0:8} ${end:8:2}" +%s` datestr=`date -d @${begin} +%Y%m%d%H` let begin=$begin+3600 while [ $begin -le $end ] do hr=`date -d @${begin} +%Y%m%d%H` datestr="$datestr,$hr" let begin=$begin+3600 done 

and this is what I got from above:

2013052100,2013052101,2013052102,...,2013052123, 2013052200,2013052201,2013052202,...,2013052223, 2013052300 
4
  • 1
    Please show your ways so we can drive you to the solution. Commented Jun 5, 2013 at 8:40
  • @fedorqui: as a matter of fact, my solution doesn't work out and looks very confusing so I'd rather start from scratch. Commented Jun 5, 2013 at 8:42
  • Well we all get sometimes so confused that we prefer to start from scratch. Anyway, it is good to show at least some pseudocode, the calling of the variables, the structure of your program... it leads to better answers, believe me. Commented Jun 5, 2013 at 8:49
  • For example, do you get the data from the user or is it hardcoded? And what about the hour? Commented Jun 5, 2013 at 8:50

2 Answers 2

2

You can use date and brace expansion:

date=20130522 echo $(date -d "-1 day $date" +%Y%m%d){12..23} \ "$date"{00..23} \ $(date -d "+1 day $date" +%Y%m%d)00 

Output (wrapped):

2013052112 2013052113 2013052114 2013052115 2013052116 2013052117 2013052118 2013052119 2013052120 2013052121 2013052122 2013052123 2013052200 2013052201 2013052202 2013052203 2013052204 2013052205 2013052206 2013052207 2013052208 2013052209 2013052210 2013052211 2013052212 2013052213 2013052214 2013052215 2013052216 2013052217 2013052218 2013052219 2013052220 2013052221 2013052222 2013052223 2013052300 
Sign up to request clarification or add additional context in comments.

2 Comments

from your solution I've only got the hour in H format instead HH, e.g. ...201305221 201305222 201305223 201305224 201305225 201305226 201305227 201305228 201305229...
@Rock: Your bash is probably too old for this feature. Change {00...23} to {0{0..9},{10..23}}.
1

Your code was quite well. What I think is that you used so much bash conversion, while date is very powerful and handles in an easier way.

I rewrited something and now I get this:

day=20130522 begin=$(date --date "$day -12 hours" "+%s") end=$(date --date "$day +1 day" "+%s") hr=$(date --date "@$begin" "+%s") while [[ $hr -lt $end ]] do hr=$(($hr + 3600)) echo $(date -d "@$hr" "+%Y%m%d %H") done $ ./script 20130521 13 20130521 14 .../... 20130522 22 20130522 23 20130523 00 

2 Comments

Nice! This is much cleaner than mine. Thanks!
Hope it helps :) See your code was a good refer point, you were quite close from the solution.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.