Bash on macOS - Get a list of dates for every Saturday on a given year

非 Y 不嫁゛ 提交于 2019-12-10 15:58:52

问题


In bash on macOS, I would like to write a small script with dates (or any other program that would do) that gives me a list of dates in the format yyyymmdd of every Saturday of a given year and saves it to a variable.

For example, if I wanted to have a list of dates for all Saturdays of the year 1850, it should somehow look like this:

var = [ 18500105, 18500112, 18500119, …, 18501228 ]

with the below code:

list=()
for month in `seq -w 1 12`; do
    for day in `seq -w 1 31`; do
    list=( $(gdate -d "1850$month$day" '+%A %Y%m%d' | grep 'Saturday' | egrep -o '[[:digit:]]{4}[[:digit:]]{2}[[:digit:]]{2}' | tee /dev/tty) )
    done
done

However, the above command does not write anything in the array list although it gives me the right output with tee.

How can I fix these issues?


回答1:


Modifying Dennis Williamson's answer slightly to suit your requirement and to add the results into the array. Works on the GNU date and not on FreeBSD's version.

#!/usr/bin/env bash
y=1850

for d in {0..6}
do
    # Identify the first day of the year that is a Saturday and break out of
    # the loop
    if (( $(date -d "$y-1-1 + $d day" '+%u') == 6))
    then
        break
    fi
done

array=()
# Loop until the last day of the year, increment 7 days at a
# time and append the results to the array
for ((w = d; w <= $(date -d "$y-12-31" '+%j'); w += 7))
do
    array+=( $(date -d "$y-1-1 + $w day" '+%Y%m%d') )
done

Now you can just print the results as

printf '%s\n' "${array[@]}"

To set up the GNU date on MacOS you need to do brew install coreutils and access the command as gdate to distinguish it from the native version provided.




回答2:


Argh, just realised you need it for MacOS date.

I will leave the answer for others that do not have that restriction, but it will not work for you.

This is not quite what you want, but close:

year=1850
firstsat=$(date -d $year-01-01-$(date -d $year-01-01 +%w)days+6days +%Y%m%d)
parset a 'date -d '$firstsat'+{=$_*=7=}days +%Y%m%d' ::: {0..52}
echo ${a[@]}

It has the bug, that it finds the next 53 Saturdays, and the last of those may not be in current year.

parset is part of GNU Parallel.




回答3:


I didn't do much error checking, but here's another implementation.
Takes day of week and target year as arguments.

Gets the julian day of the first matching weekday requested - gets the epoch seconds of noon on that day - as long as the year matches what was requested, adds that date to the array and adds a week's worth of seconds to the tracking variable.

Lather, rinse, repeat until no longer in that year.

$: typeset -f alldays
alldays () { local dow=$1 year=$2 julian=1;
  until [[ "$dow" == "$( date +%a -d $year-01-0$julian )" ]]; do (( julian++ )); done;
  es=$( date +%s -d "12pm $year-01-0$julian" );
  allhits=( $( while [[ $year == "$( date +%Y -d @$es )" ]]; do date +%Y%m%d -d @$es; (( es+=604800 )); done; ) )
}
$: time alldays Sat 1850
real    0m9.931s
user    0m1.025s
sys     0m6.695s

$: printf "%s\n" "${allhits[@]}"
18500105
18500112
18500119
18500126
18500202
18500209
18500216
18500223
18500302
18500309
18500316
18500323
18500330
18500406
18500413
18500420
18500427
18500504
18500511
18500518
18500525
18500601
18500608
18500615
18500622
18500629
18500706
18500713
18500720
18500727
18500803
18500810
18500817
18500824
18500831
18500907
18500914
18500921
18500928
18501005
18501012
18501019
18501026
18501102
18501109
18501116
18501123
18501130
18501207
18501214
18501221
18501228


来源:https://stackoverflow.com/questions/55137242/bash-on-macos-get-a-list-of-dates-for-every-saturday-on-a-given-year

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!