Compare bash arrays issue

Hello everyone,
I need help comparing 2 arrays. the first array is static; the second array is not ..

array1=( "macOS Mojave" "iTunes" )
cd /Volumes
array2=( * )

# output of array2

macOS Mojave
iTunes
Mac me

The problem occurs when I compare the arrays with the following code -

 DIFF=`echo "${array1[@]}" "${array2[@]}" | tr ' ' '\n' | sort | uniq -u`

for x in "${DIFF[@]}"
        do
                echo -e "$x"
        done

# wrong result

Mac
me

# desired result

Mac me

I'm sending the output via email and it still splits up "Mac" "me" on separate lines. How could I keep the DIFF array intact? Not separating the words when I do the compare?

Indeed, the operation should be line based, rather than word based, since file names can have spaces in them.

Compare:

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

with:

printf "%s\n" "${array1[@]}" "${array2[@]}" | sort | uniq -u

--
Note: File names could even have newlines in them, but it is rare so let's leave that for now......

1 Like

$DIFF in not an array but a scalar variable.
Try also

IFS=$'\n'
echo "${array1
[*]}"$'\n'"${array2
[*]}" | sort | uniq -u
Mac me

Don't forget to reset IFS to your default value.

1 Like

Your suggestions work for outputting to standard output but as I was testing the email portion, if there are 2 entries as differences - it treated them as 1 element in the array as oppose to 2 elements. I was hoping to have both differences in the array as its own element.

length=${#DIFF[@]}
for (( i=0; i<${length}; i++ ));
do
echo ${DIFF}
done

# wrong result

DIFF[0] Mac me 
Windows
DIFF[0] Mac me Windows

# Desired result

DIFF[0] Mac me
DIFF[1] Windows

Again: DIFF is a scalar NOT an array the way you create / populate it. There is NO ${DIFF[1]} !

Wouldn't it be better to show the big picture of your problem, so a tailored solution can be found? What are you after, in the end?

Here is the code I'm working on. After comparing both arrays, if multiple differences are detected between arr1 and arr2. I should be able to send an email for each difference found. Below, looks like I'm still treating the scalar as an array? Is there a way to make the scalar into array after comparing so I can access the elements individually?

arr1=( "macOS Mojave" "iTunes" )
cd /Volumes
arr2=( * )

IFS=$'\n'
DIFF=`echo "${arr1[*]}"$'\n'"${arr2[*]}" | sort | uniq -u`
VOLCOUNT=`printf "%s\n" "${arr1[@]}" "${arr2[@]}" | sort | uniq -u | wc -l`
if [ "$VOLCOUNT" -gt "$COUNT" ]; then
        for x in "${DIFF[@]}"
        do
                echo -e "To: ${TO}\nSubject: Alert: ${SUBJECT}$x \n\n$SIGN" | $MAIL -a gmail ${TO}
        done
else
        >/dev/null 2>&1
fi
unset $IFS
exit 0

Yes. You did it twice with arr1 and arr2 . It can vary from shell to shell, so it's best to always post your OS and shell.

Don't unset IFS - reset it to its former (saved!?) value.