Bash“if number in array”还考虑部分匹配。如何解决这个问题?
我编写了以下bash代码:Bash“if number in array”还考虑部分匹配。如何解决这个问题?,bash,Bash,我编写了以下bash代码: NStep=25 NTotal=435 Redone=('375' '400' '425' 'last') for i in $(seq 0 $NStep $NTotal) do if [[ "${Redone[@]}" =~ "$i" ]]; then echo "do something" else echo "do something else" fi done 但是,对于步骤0、25和75,它输入if语
NStep=25
NTotal=435
Redone=('375' '400' '425' 'last')
for i in $(seq 0 $NStep $NTotal)
do
if [[ "${Redone[@]}" =~ "$i" ]]; then
echo "do something"
else
echo "do something else"
fi
done
但是,对于步骤0、25和75,它输入if语句并执行某些操作,而我希望它输入else语句并执行其他操作。如何使我的正则表达式更具体或重写if语句
谢谢在bash中,正则表达式不必匹配整个字符串。您需要说数字应该用空格或字符串的开头或结尾包装:
if [[ "${Redone[@]}" =~ (^| )"$i"( |$) ]]; then
在bash中,正则表达式不必匹配整个字符串。您需要说数字应该用空格或字符串的开头或结尾包装:
if [[ "${Redone[@]}" =~ (^| )"$i"( |$) ]]; then
正则表达式匹配导致部分匹配,我更喜欢更具体的解决方案
NStep=25
NTotal=435
Redone=('375' '400' '425' 'last')
for i in $(seq 0 $NStep $NTotal)
do
isPresent=0
for redone in "${Redone[@]}"
do
if [ "${redone}" = "${i}" ]
then
isPresent=1
break
fi
done
if [[ "${isPresent}" -eq "1" ]]; then
echo "do something"
else
echo "do something else"
fi
done
正则表达式匹配导致部分匹配,我更喜欢更具体的解决方案
NStep=25
NTotal=435
Redone=('375' '400' '425' 'last')
for i in $(seq 0 $NStep $NTotal)
do
isPresent=0
for redone in "${Redone[@]}"
do
if [ "${redone}" = "${i}" ]
then
isPresent=1
break
fi
done
if [[ "${isPresent}" -eq "1" ]]; then
echo "do something"
else
echo "do something else"
fi
done
使用关联数组,而不是索引数组。另外,不要使用seq;改为使用C样式作为循环
NStep=25
NTotal=435
declare -A Redone=([375]= [400]= [425]= [last]=)
for ((i=0; i<= $NTotal; i+=$NStep))
do
if [[ -v Redone[$i] ]]; then
echo "do something"
else
echo "do something else"
fi
done
由于使用空字符串作为每个的值,${Redone[$i]+x}仅当$i是数组中的键时才会扩展到x。使用关联数组,而不是索引数组。另外,不要使用seq;改为使用C样式作为循环
NStep=25
NTotal=435
declare -A Redone=([375]= [400]= [425]= [last]=)
for ((i=0; i<= $NTotal; i+=$NStep))
do
if [[ -v Redone[$i] ]]; then
echo "do something"
else
echo "do something else"
fi
done
由于使用空字符串作为每个元素的值,${Redone[$i]+x}仅当$i是数组中的键时才会扩展到x。有许多方法可以检查数组中是否包含元素:
NStep=25
NTotal=435
Redone=('375' '400' '425' 'last')
for i in $(seq 0 $NStep $NTotal)
do
if printf "%s\0" "${Redone[@]}" | grep -F -x -q -z "$i"; then
# or if printf "%s\n" "${Redone[@]}" | grep -F -x -q "$i";
echo "do something"
else
echo "do something else"
fi
done
但我认为只使用您不感兴趣的过滤元件会更简单:
comm -12 <(printf "%s\n" "${Redone[@]}" | sort) <(seq 0 "$NStep" "$NTotal" | sort)
# outputs 375 400 425
检查数组中是否包含元素的方法有很多:
NStep=25
NTotal=435
Redone=('375' '400' '425' 'last')
for i in $(seq 0 $NStep $NTotal)
do
if printf "%s\0" "${Redone[@]}" | grep -F -x -q -z "$i"; then
# or if printf "%s\n" "${Redone[@]}" | grep -F -x -q "$i";
echo "do something"
else
echo "do something else"
fi
done
但我认为只使用您不感兴趣的过滤元件会更简单:
comm -12 <(printf "%s\n" "${Redone[@]}" | sort) <(seq 0 "$NStep" "$NTotal" | sort)
# outputs 375 400 425
问题中没有任何东西表明单词可以被空格包围。@Barmar:这就是[@]索引数组在=~regex match中展开的方式。不过,我没有在ManBash中看到它的记录。此外,这不是一个通用的解决方案,因为数组可以包含“375 400”作为单个元素。我误读了代码,认为它在数组元素上循环,而不是一次匹配整个数组。问题中没有任何东西表明单词可以被空格包围。@Barmar:这就是[@]索引数组在=~regex match中展开。不过,我没有在ManBash中看到它的记录。另外,这不是一个通用的解决方案,因为数组可以包含单个元素“375 400”。我误读了代码,认为它在数组元素上循环,而不是一次匹配整个数组。为什么要使用正则表达式?为什么不使用相等运算来查找精确匹配?因为这样我就必须添加一个额外的循环。这就是add-w to seqWhy regex?为什么不使用相等操作来查找精确匹配?因为这样我就必须添加一个额外的循环。答案是add-w to seq您的解决方案对我有效我使用的是GNU bash,版本4.2.462release。谢谢我正在使用GNU bash,版本4.2.462release,您的变通方法对我很有效。谢谢