如何收缩 /bin/sh 中具有多个 var 值的 test -eq 表达式

如何收缩 /bin/sh 中具有多个 var 值的 test -eq 表达式
#!/bin/sh
if [ $num -eq 9 -o $num -eq 75 -o $num -eq 200 ]; then
    echo "do this"
elif [ $num -eq 40 -o $num -eq 53 -o $num -eq 63]; then
    echo "do something for this"
else
    echo "for other do this"
fi

还有其他方法可以缩小语句中的表达式吗if?也许像

[ $num -eq (9,75,200) ]

顺便说一句,我在这个操作系统上没有 GNU utils。

答案1

有时不同的结构可能会更具可读性:

case $num in
9|75|200) echo "do this" ;;
40|53|63) echo "do something for this" ;;
*)        echo "for other do this" ;;
esac

答案2

小心,posix 没有定义超过 4 个参数的测试,所以你的测试结构是不明确的。看到第六次重击陷阱

因此,如果使用测试,您需要更详细:

if [ "$arg" = 9 ] || [ "$arg" = 75 ] || [ "$arg" = 200 ]

或使用案例代替

case "$arg" in
     9|75|200)  do something ; ;
     40|53|63)  do that ;;
      *)  else ... ;;
 esac

答案3

这听起来像是一个函数的工作:

test_num() {
  n=$1; shift
  for arg do
    [ "$arg" -eq "$n" ] && return 0
  done
} 2>/dev/null

if test_num "$num" 9 75 200; then
  echo "do this"
elif test_num "$num" 40 53 63; then
  echo "do something for this"
else
  echo "for other do this"
fi

答案4

另一种 POSIX 解决方案:

if     printf '%s' "$num" | grep -xE '(9|75|200)' >/dev/null; then
       echo "do this"
elif   printf '%s' "$num" | grep -xE '(40|53|63)' >/dev/null; then
       echo "do something for this"
else
       echo "for other do this" 
fi

这非常慢,比该case选项慢 50 倍。


这是一个更短的脚本,我相信是一个更简单的脚本,只有 case 选项时间的两倍:

#!/bin/sh

num="$1"    a='9 75 200'    b='40 53 63'

tnum() {
    for    arg
    do     [ "$arg" = "$num" ] && return 0
    done   return 1
}

if     tnum $a; then
            echo "do this"
elif   tnum $b; then
            echo "do something for this"
else
            echo "for other do this"
fi

注意:没有任何测试[ "$arg" = "$num" ]在所有情况下都有效,00 = 0例如,此测试会失败。
并且数值测试[ "$arg" -eq "$num" ]将无法匹配空值[ "" -eq "" ]

您可以选择最适合您情况的方法。

相关内容