I have a String Variable possible having combinations of Values as Below -
v="2020-01-2020-04,2020-11"
I want the Above values to be converted to an Array as below-
array=(2020-01,2020-02,2020-03,2020-04,2020-11)
Can anyone please help me how can i implement this and interpret the Range part and extract the data in Array accordingly?
Note the Values in the String are Monthdate in Format YYYY-MM
CodePudding user response:
Generating the ranges and storing the dates in a bash array:
- First define a function that adds a month to a date:
nextdate() {
local y m
IFS='-' read y m <<< "$1"
if [ "$m" == 12 ]
then
m=1 y=$(( 10#$y 1 ))
else
m=$(( 10#$m 1 ))
fi
printf 'd-d\n' "$y" "$m"
}
or something trivial with GNU date:
nextdate() { date -d "$1-01 1month" ' %Y-%m'; }
- Then use it in the main loop that fills the array:
v="2020-01-2020-04,2020-11"
array=()
for date in ${v//,/ }
do
[[ $date =~ ^([0-9]{4}-(0[1-9]|1[0-2]))(-([0-9]{4}-(0[1-9]|1[0-2])))?$ ]] || continue
inidate=${BASH_REMATCH[1]}
enddate=${BASH_REMATCH[4]:-$inidate}
until [ "$inidate" == "$enddate" ]
do
array =( "$inidate" )
inidate=$(nextdate "$inidate")
done
array =( "$inidate" )
done
- And you'll get:
declare -p array
# declare -a array='([0]="2020-01" [1]="2020-02" [2]="2020-03" [3]="2020-04" [4]="2020-11")'
CodePudding user response:
With bash, would you please try the following:
#!/bin/bash
v="2020-01-2020-04,2020-11"
IFS=, read -ra a <<< "$v" # split $v on comma(s) into an array a
for i in "${a[@]}"; do
if [[ $i =~ ^[0-9]{4}-[0-9]{2}$ ]]; then
array =("$i") # single YYYY-MM
elif [[ $i =~ ^([0-9]{4})-([0-9]{2})-([0-9]{4})-([0-9]{2})$ ]]; then
# range of two YYYY-MM's
if (( 10#${BASH_REMATCH[1]} != 10#${BASH_REMATCH[3]} )); then
echo "the range of year not supported."
exit 1
else
for (( j = 10#${BASH_REMATCH[2]}; j <= ${BASH_REMATCH[4]}; j )); do
# expand the range of months
array =( "$(printf "d-d" $((10#${BASH_REMATCH[1]})) "$j")" )
done
fi
fi
done
(IFS=","; echo "${array[*]}") # print the result
Output:
2020-01,2020-02,2020-03,2020-04,2020-11
