Bash

測試數組中是否存在重複值

  • April 14, 2022

我試圖找到一種簡單的方法來測試數組中的重複值。能夠辨識具有重複項的特定行會很好,但並非完全必要,但重要的是能夠看到存在重複項。

我有一個數組,$key_array其中包含一些數字:

# echo ${key_array[@]}
1 2 3 4 3 3

這個數組可以有任意數量的數字,其中一些可能是其他的重複。它們將只是整數。(以 a 開頭的數字0,例如03,根本不應該進入數組,但如果發生這種情況的機會不大,擷取303作為彼此的副本將比將它們視為不同的數字更好。)

我需要確定這些數字是否重複。我在想如果沒有別的,這可以用退出程式碼來完成。我所追求的是這樣的:

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

最後的想法是腳本通知使用者並在有重複項時退出(辨識重複項在哪裡不是超級重要,只是告訴使用者檢查重複項就足夠了),或者如果沒有任何重複項,它繼續執行並執行許多其他東西。

我將如何最好地做到這一點?

假設arr僅包含整數並且零填充數字應被視為重複(例如,01是 的副本1),我們可以使用第二個數組來保留在解析第一個數組的每個元素時已經“看到”的值arr

#!/bin/bash
arr=(1 2 3 4 3 3)
seen=()

for i in "${arr[@]}"; do
   #Remove padding zeroes, if any
   i=$((10#$i))
   # If element of arr is not in seen, add it as a key to seen
   if [ -z "${seen[i]}" ]; then
       seen[i]=1
   else
       echo "Array contains a duplicate."
       break
   fi
done

zsh外殼中:

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

Where${(u)array}擴展為數組的唯一元素,因此我們只是將元素的數量與唯一元素的數量進行比較。

bashshell 沒有等價物,但由於它的數組無論如何都不能包含 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

其中,如果元素是逐字節相同的,則元素被認為是重複的,而不是如果它們的數值相同(如果有的話)(1, 01, 0x1, 1e0, 2-1, $'1\n',' 1'都被認為是不同的)。

引用自:https://unix.stackexchange.com/questions/606259