I need to get the list of all Saturdays in a given date range ex: 20170101 to 20170630 in YYYYMMDD format in linux
4 Answers
Using GNU date and brute force:
start=20170101 end=20170630 cur=$start increment="1 day" while [ $(date +%s -d "$cur") -le $(date +%s -d "$end") ] do if [ "$(date +%A -d "$cur")" = "Saturday" ] then printf "%s\n" "$cur" increment="1 week" fi cur=$(date +%Y%m%d -d "$cur + $increment") done - I think Linux Journal had an article similar to this question, but they used the
calprogram. I can't find it now, of course.KevinO– KevinO2017-06-19 15:35:31 +00:00Commented Jun 19, 2017 at 15:35 - Maybe it was this one? Just beware if
calunderlines today: unix.stackexchange.com/q/346153/1175492017-06-20 12:06:02 +00:00Commented Jun 20, 2017 at 12:06
Make a script with this:
#! /bin/bash cur=20170101 end=20170630 # First upcoming saturday is: cur=$(( cur+(6-$( date -d $cur +%w )) )) # Keep increment by 7 days until 'end' while (( end>cur )); do echo $cur cur=$( date -d "$cur+7days" +%Y%m%d ) done It will give:
$ ./ILoveSaturdays.bash 20170107 20170114 ... 20170617 20170624 - You beat me to it! The offset from date +%W is wrong if the start date is a Saturday, though.tripleee– tripleee2017-06-19 17:55:18 +00:00Commented Jun 19, 2017 at 17:55
- @tripleee If you start on a Saturday, %w would be 6, and 6-6 = 0. I guess it should work.hschou– hschou2017-06-19 18:03:05 +00:00Commented Jun 19, 2017 at 18:03
With GNU date, trying to run as few date commands as possible (2):
TZ=UTC0 date -f - '+%s %w' << EOF | 20170101 20170630 EOF awk -v d=86400 '{ d1 = $1 + (6 - $2) * d getline for (t = d1; t <= $1; t += 7 * d) print "@" t}' | TZ=UTC0 date -f - +%Y%m%d Let's do this in perl :
perl -e ' use POSIX "strftime"; $start=$ARGV[0]; $end=$ARGV[1]; if(! ($start =~ /^(\d\d\d\d)(\d\d)(\d\d)$/)){ die "bad format for first arg"; } $epoch=(($1-1970)*365+($2-1)*28+$3-1)*24*60*60; if(! ($end =~ /^(\d\d\d\d)(\d\d)(\d\d)$/)){ die "bad format for first arg"; } while(1){ $cur=strftime("%Y%m%d", gmtime $epoch); if($cur ge $start){last;}; $epoch += 24*60*60; } while(1){ $wd = strftime("%u", gmtime $epoch); $cur = strftime("%Y%m%d", gmtime $epoch); if($cur >= $end){last;} if($wd == 6){ printf "$cur\n"; } $epoch += 24*60*60; }' 20170101 20170630