나는 다음 스크립트를 가지고 있으며 이 경우 for 루프가 내가 지정한 순서대로 실행된다는 것을 알았습니다. 2018년, 2019년, 2020년이 될 것으로 예상됐으나 결과는 2019년, 2018년, 2020년이 됐다.
쉘 스크립트에 이에 대한 특별한 이유가 있고 순서를 보존할 수 있는 방법이 있습니까?
#!/bin/sh
declare -A arr
arr=( ["2018"]=5%12 ["2019"]=1%12 ["2020"]=1%2 )
INPUT_MONTH=$2
INPUT_YEAR=$1
#For loop to iterate the year(key) value of array
for year in ${!arr[@]}; do
echo ${year} ${arr[${year}]}
MONTH_RANGE=${arr[${year}]}
if [ ${year} -ge ${INPUT_YEAR} ]; then
START_MONTH=$(echo "${MONTH_RANGE}" | cut -d'%' -f 1)
END_MONTH=$(echo "${MONTH_RANGE}" | cut -d'%' -f 2)
# input year is equal and input month is different from default start one.
if [ "${year}" == "${INPUT_YEAR}" ]; then
START_MONTH=$INPUT_MONTH
fi
for mon in $(seq $START_MONTH $END_MONTH); do
echo "Process year:month <=> ${year}:${mon}"
done;
else
continue;
fi
done;
산출:
2019 1%12
Process year:month <=> 2019:1
Process year:month <=> 2019:2
Process year:month <=> 2019:3
Process year:month <=> 2019:4
Process year:month <=> 2019:5
Process year:month <=> 2019:6
Process year:month <=> 2019:7
Process year:month <=> 2019:8
Process year:month <=> 2019:9
Process year:month <=> 2019:10
Process year:month <=> 2019:11
Process year:month <=> 2019:12
2018 5%12
Process year:month <=> 2018:4
Process year:month <=> 2018:5
Process year:month <=> 2018:6
Process year:month <=> 2018:7
Process year:month <=> 2018:8
Process year:month <=> 2018:9
Process year:month <=> 2018:10
Process year:month <=> 2018:11
Process year:month <=> 2018:12
2020 1%2
Process year:month <=> 2020:1
Process year:month <=> 2020:2
답변1
Bash에서 declare -A arr
다음을 선언하세요.연관대량으로. 연관 배열의 키는 해시되며 순회 순서는 ${!arr[@]}
보장 되지 않습니다 1 .
$ declare -A arr
$ arr=( ["2018"]=5%12 ["2019"]=1%12 ["2020"]=1%2 )
$ for year in "${!arr[@]}"; do printf '%s: %s\n' "${year}" "${arr[${year}]}"; done
2019: 1%12
2018: 5%12
2020: 1%2
대신 declare -a arr
에색인배열은 예상대로 정렬되어야 합니다.
$ declare -a arr
$ arr=( [2018]=5%12 [2019]=1%12 [2020]=1%2 )
$ for year in "${!arr[@]}"; do printf '%s: %s\n' "${year}" "${arr[${year}]}"; done
2018: 5%12
2019: 1%12
2020: 1%2
키(연도)는 숫자이므로 이 경우 인덱스 배열을 사용하지 않을 이유가 없는 것 같습니다.
인용하다:
답변2
이 경우 키는 숫자이므로 Steeldriver의 솔루션을 사용할 수 있습니다.
일반적인 접근 방식은 키 순서에 대한 추가 배열을 제공하는 것입니다.
declare -a ordered_keys
ordered_keys=(2018 2019 2020)
# or dynamically
ordered_keys=($(for key in "${!arr[@]}"; do printf '%s\n' "$key"; done | sort))
그런 다음 교체
for year in ${!arr[@]}; do
당신은 그렇습니다
for key in "${ordered_keys[@]}"; do