Commit | Line | Data |
---|---|---|
fc69a020 SBS |
1 | #!/usr/bin/env bash |
2 | # Desc: Prints days | |
3 | # Depends: date (GNU Coreutils 8.32) | |
4 | # Version: 0.0.1 | |
5 | # Ref/Attrib: [1] Template:This date in recent years https://en.wikipedia.org/wiki/Template:This_date_in_recent_years | |
6 | # [2] Removing leading zeros before passing a shell variable to another command https://stackoverflow.com/a/11130324 | |
7 | ||
8 | declare -g yearRange; # range of years to consider | |
9 | ||
10 | yell() { echo "$0: $*" >&2; } #o Yell, Die, Try Three-Fingered Claw technique | |
11 | die() { yell "$*"; exit 111; } #o Ref/Attrib: https://stackoverflow.com/a/25515370 | |
12 | try() { "$@" || die "cannot $*"; } #o | |
13 | vbm() { | |
14 | # Description: Prints verbose message ("vbm") to stderr if opVerbose is set to "true". | |
15 | # Usage: vbm "DEBUG :verbose message here" | |
16 | # Version 0.2.0 | |
17 | # Input: arg1: string | |
18 | # vars: opVerbose | |
19 | # Output: stderr | |
20 | # Depends: bash 5.1.16, GNU-coreutils 8.30 (echo, date) | |
21 | ||
22 | if [ "$opVerbose" = "true" ]; then | |
23 | functionTime="$(date --iso-8601=ns)"; # Save current time in nano seconds. | |
24 | echo "[$functionTime]:$0:""$*" 1>&2; # Display argument text. | |
25 | fi | |
26 | ||
27 | # End function | |
28 | return 0; # Function finished. | |
29 | } # Displays message if opVerbose true | |
30 | showUsage() { | |
31 | # Desc: Display script usage information | |
32 | # Usage: showUsage | |
33 | # Version 0.0.2 | |
34 | # Input: none | |
35 | # Output: stdout | |
36 | # Depends: GNU-coreutils 8.30 (cat) | |
37 | cat <<'EOF' | |
38 | USAGE: | |
39 | bk_this-date-in-recent-years.sh [ options ] [str day of month] | |
40 | ||
41 | OPTIONS: | |
42 | -h, --help | |
43 | Display help information. | |
44 | --version | |
45 | Display script version. | |
46 | -v, --verbose | |
47 | Display debugging info. | |
48 | -r, --iso-range | |
49 | Specify year range (iso-8601 period), e.g. | |
50 | "2010/2020". By default, most recent 10 | |
51 | years are considered. | |
52 | -- | |
53 | Indicate end of options. | |
54 | ||
55 | EXAMPLE: | |
56 | bk_this_date-in-recent-years.sh "05-11" | |
57 | bk_this_date-in-recent-years.sh -r "1990/2020" "05-11" | |
58 | bk_this_date-in-recent-years.sh -r "1990/2020" -- "05-11" | |
59 | EOF | |
60 | } # Display information on how to use this script. | |
61 | processArgs() { | |
62 | # Desc: Processes arguments provided to script. | |
63 | # Usage: processArgs "$@" | |
64 | # Version: 1.0.0 | |
65 | # Input: "$@" (list of arguments provided to the function) | |
66 | # yearRange Iso date range to consider (e.g. "1999/2020"). | |
67 | # Output: Sets following variables used by other functions: | |
68 | # opVerbose Indicates verbose mode enable status. (ex: "true", "false") | |
69 | # opIsoRange Indicates that an iso-8601 date range is specified. (ex: "true", "false") | |
70 | # yearRange Iso date range to consider (e.g. "1999/2020"). | |
71 | # arrayPosArgs Array of remaining positional argments | |
72 | # Depends: | |
73 | # yell() Displays messages to stderr. | |
74 | # vbm() Displays messsages to stderr if opVerbose set to "true". | |
75 | # showUsage() Displays usage information about parent script. | |
76 | # showVersion() Displays version about parent script. | |
77 | # arrayPosArgs Global array for storing non-option positional arguments (i.e. arguments following the `--` option). | |
78 | # External dependencies: bash (5.1.16), echo | |
79 | # Ref./Attrib.: | |
80 | # [1]: Marco Aurelio (2014-05-08). "echo that outputs to stderr". https://stackoverflow.com/a/23550347 | |
81 | # [2]: "Handling positional parameters" (2018-05-12). https://wiki.bash-hackers.org/scripting/posparams | |
82 | ||
83 | # Initialize function | |
84 | vbm "DEBUG:processArgs function called." | |
85 | ||
86 | # Perform work | |
87 | while [ ! $# -eq 0 ]; do # While number of arguments ($#) is not (!) equal to (-eq) zero (0). | |
88 | #yell "DEBUG:Starting processArgs while loop." # Debug stderr message. See [1]. | |
89 | #yell "DEBUG:Provided arguments are:""$*" # Debug stderr message. See [1]. | |
90 | case "$1" in | |
91 | -h | --help) showUsage; exit 1;; # Display usage. | |
92 | --version) showVersion; exit 1;; # Show version | |
93 | -v | --verbose) opVerbose="true"; vbm "DEBUG:Verbose mode enabled.";; # Enable verbose mode. See [1]. | |
94 | -r | --iso-range) | |
95 | opIsoRange="true"; vbm "DEBUG:Accepting iso-8601 year range."; # Accept iso-8601 year range. | |
96 | shift; | |
97 | yearRange="$1";; | |
98 | --) # End of all options. See [2]. | |
99 | shift; | |
100 | for arg in "$@"; do | |
101 | vbm "DEBUG:adding to arrayPosArgs:$arg"; | |
102 | arrayPosArgs+=("$arg"); | |
103 | done; | |
104 | break;; | |
105 | -*) showUsage; yell "ERROR: Unrecognized option."; exit 1;; # Display usage | |
106 | *) for arg in "$@"; do | |
107 | vbm "DEBUG:adding to arrayPosArgs:$arg"; | |
108 | arrayPosArgs+=("$arg"); | |
109 | done; | |
110 | break;; | |
111 | esac | |
112 | shift | |
113 | done | |
114 | ||
115 | # End function | |
116 | vbm "DEBUG:processArgs function ended." | |
117 | return 0; # Function finished. | |
118 | } # Evaluate script options from positional arguments (ex: $1, $2, $3, etc.). | |
119 | validatePosArgs() { | |
120 | # Input: arrayPosArgs array with positional arguments | |
121 | # opVerbose bool indicates to vbm() to display verbose text | |
122 | # opIsoRange bool indicates to use a user-provided year range | |
123 | # yearRange str iso-8601 year range provided by -r, --iso-range option | |
124 | ||
125 | # Validate year $range | |
126 | re='^[0-9]+/[0-9]+$'; # Simply check (int)/(int). Don't address Gregorian Calendar here. | |
127 | if [[ $opIsoRange == "true" && ! "$yearRange" =~ $re ]] ; then | |
128 | showUsage; | |
129 | yell "ERROR:Not a valid date range (e.g. 2010/2022):$yearRange"; | |
130 | return 1; | |
131 | fi; | |
132 | return 0; | |
133 | }; # Validate arguments | |
134 | main() { | |
135 | # Input: arrayPosArgs array with positional arguments | |
136 | # opVerbose bool indicates to vbm() to display verbose text | |
137 | # opIsoRange bool indicates to use a user-provided year range | |
138 | # yearRange str iso-8601 year range provided by -r, --iso-range option | |
139 | # Output: stdout: dates with days of the week (newline delimited) | |
140 | # Depends: date (GNU Coreutils 8.32) | |
141 | # Depends: processArgs(), yell(), vbm(), showUsage(), showVersion(), validatePosArgs() | |
142 | local dom yc ymin ymax; | |
143 | ||
144 | # Check input | |
145 | processArgs "$@"; | |
146 | if ! validatePosArgs; then | |
147 | die "FATAL:Invalid positional arguments:$(declare -p arrayPosArgs)"; | |
148 | fi; | |
149 | ||
150 | # Define year range | |
151 | if [[ ! $opIsoRange == "true" ]]; then | |
152 | ## Default: Most recent 10 years | |
153 | yc="10"; # count of years to consider | |
154 | ymax="$(date +%Y)"; # highest year to consider | |
155 | ymin="$((ymax - yc))"; # earliest year to consider | |
156 | else | |
157 | ## Provided via -r,--iso-range option | |
158 | ymin="$(echo "$yearRange" | cut -d'/' -f1)"; | |
159 | ymin="$((10#$ymin))"; # strip leading zeroes. See [2] | |
160 | ymax="$(echo "$yearRange" | cut -d'/' -f2)"; # See [2] | |
161 | ymax="$((10#$ymax))"; # strip leading zeroes. See [2] | |
162 | yc="$((ymax - ymin + 1))"; | |
163 | fi; | |
164 | # yell "DEBUG:ymin:$ymin"; | |
165 | # yell "DEBUG:ymax:$ymax"; | |
166 | # yell "DEBUG:yc :$yc"; | |
167 | ||
168 | # Check year range | |
169 | if ! [[ $(( ymax - ymin )) -ge 0 ]]; then die "FATAL:Invalid year range:$yearRange"; fi; | |
170 | ||
171 | # Print Output | |
172 | ## Get day of month (first positional argument) | |
173 | dom="${arrayPosArgs[0]}"; | |
174 | for (( year = ymin; year <= ymax; year++ )); do | |
175 | dstr="$year-$dom"; | |
176 | date +%Y-%m-%d\ %A --date="$dstr"; | |
177 | # printf "DEBUG:dom :%s\n" "$dom"; | |
178 | # printf "DEBUG:ymax:%s\n" "$ymax"; | |
179 | # printf "DEBUG:ymin:%s\n" "$ymin"; | |
180 | # printf "DEBUG:year:%s\n" "$year"; | |
181 | # printf "DEBUG:dstr:%s\n" "$dstr"; | |
182 | done; | |
183 | }; # main program | |
184 | ||
185 | main "$@"; | |
186 | ||
187 | ||
188 | ||
189 | # Author: Steven Baltakatei Sandoval | |
190 | # License: GPLv3+ | |
191 | ||
192 | # Ref/Attrib (depends) | |
193 | ||
194 | # date (GNU coreutils) 8.32 | |
195 | # Copyright (C) 2020 Free Software Foundation, Inc. | |
196 | # License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>. | |
197 | # This is free software: you are free to change and redistribute it. | |
198 | # There is NO WARRANTY, to the extent permitted by law. | |
199 | ||
200 | # Written by David MacKenzie. |