4

I have a bash array "RUN_Arr" with values as given below. If the values are same, I want the script to continue else I want to report them.

echo "${RUN_Arr[@]}"
"AHVY37BCXY" "AHVY37BCXY" "AHVY37BCXY" "AHVY38BCXY" "AHVY37BCXY" "AHVY37BCXY"

Based on the above array, I want to echo:

 No the array values are not same
 "AHVY37BCXY" "AHVY38BCXY"

Can someone suggest a solution? Thanks.

Gopinath S
  • 511
  • 6
  • 20

2 Answers2

8

Iterate through your array, and test against a watermark:

arr=(a a a b a a a)

watermark=${arr[0]}
for i in "${arr[@]}"; do
    if [[ "$watermark" != "$i" ]]; then
        not_equal=true
        break
    fi
done

[[ -n "$not_equal" ]] && echo "They are not equal ..."

Very simplistic Proof-Of-Concept for you; obviously harden as appropriate for your purposes.

hunteke
  • 3,648
  • 1
  • 7
  • 17
  • Thanks for your response, I was thinking the same approach. I am wondering if there is a function that gets the unique element in an array if so, I can report if the number of unique elements is more than one. – Gopinath S Oct 19 '17 at 20:03
  • There's no such function, per se, but that doesn't mean you couldn't write one for yourself. I might use Awk, outsource to a different language, or Bash's hash tables. Check out [How to define hash tables in Bash?](https://stackoverflow.com/questions/1494178/how-to-define-hash-tables-in-bash) – hunteke Oct 19 '17 at 20:07
4

If none of your array elements includes a newline character, you can do this:

mapfile -t uniq < <(printf "%s\n" "${RUN_Arr[@]}" | sort -u)
if (( ${#uniq[@]} > 1 )); then
    echo "The elements are not the same: ${uniq[@]}" 
    # ...

If you need to protect against elements with newline characters, there is a simple solution if you have bash 4.4 (for the -d option) and Gnu or FreeBSD sort (for the -z option):

mapfile -d '' -t uniq < <(printf "%s\n" "${RUN_Arr[@]}" | sort -zu)
if (( ${#uniq[@]} > 1 )); then
    echo "The elements are not the same: ${uniq[@]}" 
    exit 1
fi

Without bash 4.4, you could use an adaptation of @hunteke's answer:

for i in "${RUN_Arr[@]:1}"; do
    if [[ $i != ${RUN_ARR[0]} ]]; then
        printf "The elements are not the same:"
        printf "%s\0" "${RUN_Arr[@]}" |
            sort -zu |
            xargs -0 printf " %s"
        printf "\n"
        exit 1
    fi
done

(This still requires a sort which supports -z.)

rici
  • 234,347
  • 28
  • 237
  • 341