Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing two different arrays using shell script

Tags:

shell

sh

ksh

How do we compare two arrays and display the result in a shell script?

Suppose we have two arrays as below:

list1=( 10 20 30 40 50 60 90 100 101 102 103 104)
list2=( 10 20 30 40 50 60 70 80 90 100 )

My requirement is to compare these two arrays in an order that it will only display the result as (101 102 103 104) from list1. It should not include the values 70 and 80 which are present in list2 but not in list1.

This does not help since it is including everything:

echo "${list1[@]}" "${list2[@]}" | tr ' ' '\n' | sort | uniq -u

I tried something like this below, but why is it not working?

list1=( 10 20 30 40 50 60 70 90 100 101 102 103 104)
list2=( 10 20 30 40 50 60 70 80 90 100 )

for (( i=0; i<${#list1[@]}; i++ )); do
for (( j=0; j<${#list2[@]}; j++ )); do
     if [[ ${list1[@]} == ${list2[@] ]]; then
         echo 0
         break
             if [[  ${#list2[@]} == ${#list1[@]-1} && ${list1[@]} != ${list2[@]} ]];then
             echo ${list3[$i]}
         fi
     fi
done
done
like image 372
DBA Avatar asked Sep 17 '25 14:09

DBA


1 Answers

You can use comm for this:

readarray -t unique < <(
    comm -23 \
        <(printf '%s\n' "${list1[@]}" | sort) \
        <(printf '%s\n' "${list2[@]}" | sort)
)

resulting in

$ declare -p unique
declare -a unique=([0]="101" [1]="102" [2]="103" [3]="104")

or, to get your desired format,

$ printf '(%s)\n' "${unique[*]}"
(101 102 103 104)

comm -23 takes two sorted files (using sort here) and prints every line that is unique to the first one; process substitution is used to feed the lists into comm.

Then, readarray reads the output and puts each line into an element of the unique array. (Notice that this requires Bash.)


Your attempt failed, among other things, because you were trying to compare multiple elements in a single comparison:

[[ ${list1[@]} != ${list2[@]} ]]

expands to

[[ 10 20 30 40 50 60 90 100 101 102 103 104 != 10 20 30 40 50 60 70 80 90 100 ]]

and Bash complains about a binary operator expected instead of the second element, 20.

like image 180
Benjamin W. Avatar answered Sep 21 '25 06:09

Benjamin W.