Bash :访问数组元素(意外行为)



我想从 1 到 12 运行一个循环,将当前循环号与预定义的数组匹配,然后输出匹配的数组。

每种类型的月份都有一个数组。

lm #has 4,6,9,11 
hm #has 1,3,5,7,8,10,12 
feb #special case, if its not an hm or lm, its feb

这是我当前的代码:

#!/bin/bash
lm=()
lm+=(4)
lm+=(6)
lm+=(9)
lm+=(11)
hm=()
hm+=(1)
hm+=(3)
hm+=(5)
hm+=(7)
hm+=(8)
hm+=(10)
hm+=(12)
feb=()
feb+=(2)
ld=(1 2)
hd=(1 2)
fd=(1 2)
for m in {1..12}
do
echo "current month is $m"
if [[ " ${hm[*]} " == *"$m"* ]];
then
echo "high month"
elif [[ " ${lm[*]} " == *"$m"* ]];
then
echo "low month"
elif [[ " ${feb[*]} " = *"$m"* ]];
then
echo "feb"
else
echo "weird month input"
fi
done

其输出:

$ ./old2.sh
current month is 1
high month
current month is 2
high month
current month is 3
high month
current month is 4
low month
current month is 5
high month
current month is 6
low month
current month is 7
high month
current month is 8
high month
current month is 9
low month
current month is 10
high month
current month is 11
low month
current month is 12
high month

2,它显示为高月(hm(,即它有31天。

我已经注释掉了将在数组中添加 12 或 12 月的行:

#!/bin/bash
lm=()
lm+=(4)
lm+=(6)
lm+=(9)
lm+=(11)
hm=()
hm+=(1)
hm+=(3)
hm+=(5)
hm+=(7)
hm+=(8)
hm+=(10)
#hm+=(12)
feb=()
feb+=(2)
ld=(1 2)
hd=(1 2)
fd=(1 2)
for m in {1..12}
do
echo "current month is $m"
if [[ " ${hm[*]} " == *"$m"* ]];
then
echo "high month"
elif [[ " ${lm[*]} " == *"$m"* ]];
then
echo "low month"
elif [[ " ${feb[*]} " = *"$m"* ]];
then
echo "feb"
else
echo "weird month input"
fi
done

新输出 :

$ ./old2.sh
current month is 1
high month
current month is 2
feb
current month is 3
high month
current month is 4
low month
current month is 5
high month
current month is 6
low month
current month is 7
high month
current month is 8
high month
current month is 9
low month
current month is 10
high month
current month is 11
low month
current month is 12
weird month input

现在输出符合预期。

为什么我的脚本接受2作为hm,而不是feb,因为它应该接受?

看起来问题是您使用*"$m"*作为匹配模式,因此,当您尝试匹配 2 y 时,也匹配 12。

在您的算法中,您将整个数组用作字符串并尝试匹配一个元素。一个快速而肮脏的解决方案是在比赛周围使用空格,例如:

for m in {1..12}
do
echo "current month is $m"
if [[ " ${hm[*]} " == *" $m "* ]];
then
echo "high month"
elif [[ " ${lm[*]} " == *" $m "* ]];
then
echo "low month"
elif [[ " ${feb[*]} " == *" $m "* ]];
then
echo "feb"
else
echo "weird month input"
fi
done

在那里它将起作用,因为"2"与"12"不匹配。

但是我不认为这是最好的方法...不幸的是,bash 没有在数组中查找元素的语法,但如果您查看此答案 https://stackoverflow.com/a/8574392/6316852 有一个完全适合您需求的函数。

所以,另一种选择:

#!/bin/bash
lm=(4 6 9 11)
hm=(1 3 5 7 8 10 12)
feb=(2)
containsElement () {
local e match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 0; done
return 1
}
for m in {1..12}; do
echo "current month is $m"
if containsElement "$m" "${hm[@]}"; then
echo "high month"
elif containsElement "$m" "${lm[@]}"; then
echo "low month"
elif containsElement "$m" "${feb[@]}"; then
echo "feb"
else
echo "weird month input"
fi
done

希望对您有所帮助

相关内容

最新更新