测试数组中是否存在重复值

Kef*_*fka 2 shell scripting bash

我正在尝试找到一种简单的方法来测试数组中的重复值。能够识别具有重复项的特定行固然很好,但并非完全必要,但重要的一点是能够看到存在重复项。

我有一个数组,$key_array其中包含一些数字:

# echo ${key_array[@]}
1 2 3 4 3 3
Run Code Online (Sandbox Code Playgroud)

该数组可以有任意数量的数字,其中一些数字可能与其他数字重复。它们只是整数。(以 a 开头的数字0,例如03,根本不应该进入数组,但万一发生这种情况,捕获303作为彼此的重复项比将它们视为不同的数字更好。)

我需要确定这些数字是否重复。我想如果没有别的办法的话,这可以通过退出代码来完成。我所追求的是这样的:

if $(some command); then
 echo "Array contains duplicates."
 exit 1
fi
$(commands to run after duplicate check)
Run Code Online (Sandbox Code Playgroud)

最后的想法是,如果存在重复项,脚本会通知用户并退出(对于识别重复项在哪里并不是非常重要,只需告诉用户检查重复项就足够了),或者如果没有任何重复项,它继续运行并运行许多其他东西。

我怎样才能最好地完成这个任务?

Sté*_*las 5

在外壳中zsh

array=(1 2 3 4 3 3)
if (($#array != ${#${(u)array}})); then
  print -u2 array contains duplicates
  exit 1
fi
Run Code Online (Sandbox Code Playgroud)

where${(u)array}扩展为数组的唯一元素,因此我们只是将元素数与唯一元素数进行比较。

shellbash没有等效的东西,但由于它的数组无论如何都不能包含 NUL 字节,如果您使用的是 GNU 系统,您可以执行以下操作:

readarray -td '' dups < <(
  (( ${#array[@]} == 0 )) ||
    printf '%s\0' "${array[@]}" |
      LC_ALL=C sort -z |
      LC_ALL=C uniq -zd
)

if ((${#dups[@]} > 0)); then
  echo >&2 "array has duplicates:"
  printf >&2 ' - "%s"\n' "${dups[@]}"
  exit 1
fi
Run Code Online (Sandbox Code Playgroud)

在这些元素中,如果元素逐字节相同,则被视为重复1,而不是其数值(如果有)相同( 、010x11e02-1$'1\n'' 1'都被视为不同)。