如何在bash中测试数组元素是否全部相等?

如何在bash中测试数组元素是否全部相等?

下面的数组代表每台linux机器上的磁盘数量

每个单阵列包括磁盘上的数量Linux机器

echo ${ARRAY_DISK_Quantity[*]}
4 4 4 4 2 4 4 4

确定所有数组的值都相等的简单方法是什么?

状态良好:

4 4 4 4 4 4 4 4

状态不好:

4 4 4 4 4 4 2 4

状态不好:

6 6 6 6 6 6 6 6 6 6 2 6 2

答案1

bash+ GNU sort+ GNUgrep解决方案:

if [ "${#array[@]}" -gt 0 ] && [ $(printf "%s\000" "${array[@]}" | 
       LC_ALL=C sort -z -u |
       grep -z -c .) -eq 1 ] ; then
  echo ok
else
  echo bad
fi

英文解释:如果对数组元素进行唯一排序只会得到一个元素,则打印“ok”。否则打印“坏”。

该数组用 NUL 字节打印,分隔每个元素,通过管道输送到 GNU 排序(依赖于-zaka--zero-terminated-uaka--unique选项),然后输送到grep(使用选项-zaka--null-data-caka --count)来计算输出行数。

与我之前的版本不同,我不能wc在这里使用,因为它需要以换行符结尾的输入行...并且在使用sedtr将 NUL 转换为换行符后sort会破坏使用 NUL 分隔符的目的。 grep -c做出合理的替代。


这是将同样的事情重写为函数:

function count_unique() {
  local LC_ALL=C

  if [ "$#" -eq 0 ] ; then 
    echo 0
  else
    echo "$(printf "%s\000" "$@" |
              sort --zero-terminated --unique |
              grep --null-data --count .)"
  fi
}



ARRAY_DISK_Quantity=(4 4 4 4 2 4 4 4)

if [ "$(count_unique "${ARRAY_DISK_Quantity[@]}")" -eq 1 ] ; then
  echo "ok"
else
  echo "bad"
fi

答案2

zsh

if ((${#${(u)ARRAY_DISK_Quantity[@]}} == 1)); then
  echo OK
else
  echo not OK
fi

哪里(u)有参数扩展标志来扩展独特的价值观。所以我们得到了数组中唯一值的计数。

替换== 1<= 1你想认为空数组就可以了。

使用ksh93,您可以对数组进行排序并检查第一个元素是否与最后一个元素相同:

set -s -- "${ARRAY_DISK_Quantity[@]}"
if [ "$1" = "${@: -1}" ]; then
  echo OK
else
  echo not OK
fi

使用 ksh88 或 pdksh/mksh:

set -s -- "${ARRAY_DISK_Quantity[@]}"
if eval '[ "$1" = "${'"$#"'}" ]'; then
  echo OK
else
  echo not OK
fi

使用bash,您可能需要一个循环:

unique_values() {
  typeset i
  for i do
    [ "$1" = "$i" ] || return 1
  done
  return 0
}
if unique_values "${ARRAY_DISK_Quantity[@]}"; then
  echo OK
else
  echo not OK
fi

(可以与所有具有数组支持的类似 Bourne 的 shell(ksh、zsh、bash、yash)一起使用)。

请注意,对于空数组,它返回 OK。[ "$#" -gt 0 ] || return如果您不希望在函数的开头添加 a 。

答案3

bash+awk解决方案:

function get_status() {
    arr=("$@")    # get the array passed as argument
    if awk 'v && $1!=v{ exit 1 }{ v=$1 }' <(printf "%d\n" "${arr[@]}"); then 
        echo "status: Ok"
    else 
        echo "status: Bad"
    fi
}

测试用例#1:

ARRAY_DISK_Quantity=(4 4 4 4 4 2 4 4)
get_status "${ARRAY_DISK_Quantity[@]}"
status: Bad

测试用例#2:

ARRAY_DISK_Quantity=(4 4 4 4 4 4 4 4)
get_status "${ARRAY_DISK_Quantity[@]}"
status: Ok

答案4

使用 bash 和 GNU grep:

if grep -qE '^([0-9]+)( \1)*$' <<< "${ARRAY_DISK_Quantity[@]}"; then 
  echo "okay"
else
  echo "not okay"
fi

相关内容