Bash - fun exercises with the date command
The command
date -d mm/dd/yyyy +%W
displays the number of Mondays since the start of the year, not the number of weeks or the weak number since the start of the year.
Let’s make some data, dates for the days of the month for January 2021.
$ for k in {1..31}; do echo 1/$k/2021; done > dates1
1/1/2021
1/2/2021
1/3/2021
1/4/2021
1/5/2021
...
1/31/2021
Now the script script.sh
(adopted from here
#!/bin/bash
function process(){
echo $(date -d $1 +%A), $1, $(date -d $1 +%W)
}
echo day, date, week
while read -r line; do
process "$line"
done < $1
Now let’s process the data
./script dates1
The result is shown below
day, date, week
Friday, 1/1/2021, 00
Saturday, 1/2/2021, 00
Sunday, 1/3/2021, 00
Monday, 1/4/2021, 01
Tuesday, 1/5/2021, 01
...
Sunday, 1/31/2021, 04
let’s make this output prettier by piping the output to column -t -s,
day date week
Friday 1/1/2021 00
Saturday 1/2/2021 00
Sunday 1/3/2021 00
Monday 1/4/2021 01
Tuesday 1/5/2021 01
Wednesday 1/6/2021 01
Thursday 1/7/2021 01
Friday 1/8/2021 01
Saturday 1/9/2021 01
Sunday 1/10/2021 01
Monday 1/11/2021 02
Tuesday 1/12/2021 02
Wednesday 1/13/2021 02
Thursday 1/14/2021 02
Friday 1/15/2021 02
Saturday 1/16/2021 02
Sunday 1/17/2021 02
Monday 1/18/2021 03
Tuesday 1/19/2021 03
Wednesday 1/20/2021 03
Thursday 1/21/2021 03
Friday 1/22/2021 03
Saturday 1/23/2021 03
Sunday 1/24/2021 03
Monday 1/25/2021 04
Tuesday 1/26/2021 04
Wednesday 1/27/2021 04
Thursday 1/28/2021 04
Friday 1/29/2021 04
Saturday 1/30/2021 04
Sunday 1/31/2021 04
If you’re wondering about the end of the year, here it is.
$ for k in {1..31}; do echo `date -d 12/$k/2021 +%W`; done
48
48
48
48
48
49
49
49
49
49
49
49
50
50
50
50
50
50
50
51
51
51
51
51
51
51
52
52
52
52
52
Bonus
The following code prints all the (possible) dates of the year 2021. It uses the exit status of the date
command to filter out the impossible dates (e.g. Nov 31)
#!/bin/bash
for j in {1..12}; do
for k in {1..31}; do
date -d "$j/$k/2021" > /dev/null 2>&1
if test $? -eq 0; then
echo $(date -d "$j/$k/2021" +%m/%d/%Y)
fi
done;
done
To find the impossible dates:
#!/bin/bash
for k in {1..12}/{1..31}/2021; do
date -d $k > /dev/null 2>&1
test $? -ne 0 && echo $k
done
or better yet
#!/bin/bash
for k in {1..12}/{1..31}/2021; do
date -d $k > /dev/null 2>&1 || echo $k
done