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

yae*_*ael 15 bash array awk shell-script

以下数组表示每台 linux 机器上的磁盘数量

每个单个阵列都包含linux 机器上的磁盘数量。

echo ${ARRAY_DISK_Quantity[*]}
4 4 4 4 2 4 4 4
Run Code Online (Sandbox Code Playgroud)

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

良好状态:

4 4 4 4 4 4 4 4
Run Code Online (Sandbox Code Playgroud)

状态不佳:

4 4 4 4 4 4 2 4
Run Code Online (Sandbox Code Playgroud)

状态不佳:

6 6 6 6 6 6 6 6 6 6 2 6 2
Run Code Online (Sandbox Code Playgroud)

cas*_*cas 12

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
Run Code Online (Sandbox Code Playgroud)

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

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

与我以前的版本不同,我不能wc在这里使用,因为它需要以换行符结尾的输入行……并且在使用sedtrsortNUL转换为换行符后,会破坏使用 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
Run Code Online (Sandbox Code Playgroud)


Sté*_*las 8

zsh

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

哪里(u)是用于扩展唯一值的参数扩展标志。所以我们得到了数组中唯一值的计数。

更换== 1<= 1的是你要考虑一个空数组是确定。

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

set -s -- "${ARRAY_DISK_Quantity[@]}"
if [ "$1" = "${@: -1}" ]; then
  echo OK
else
  echo not OK
fi
Run Code Online (Sandbox Code Playgroud)

使用 ksh88 或 pdksh/mksh:

set -s -- "${ARRAY_DISK_Quantity[@]}"
if eval '[ "$1" = "${'"$#"'}" ]'; then
  echo OK
else
  echo not OK
fi
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

(适用于所有支持数组的 Bourne 类 shell(ksh、zsh、bash、yash))。

请注意,它为空数组返回 OK。[ "$#" -gt 0 ] || return如果您不想要,请在函数的开头添加一个。