Compare two arrays

Hi,

I am trying to compare two lists that are held in two variables so I believe I need to access the array elements to compare these. I am using ksh 88 and the code I have tried is below:

for file in ${origfilelist}
do
        if [[ "${file}" != $failfiles[@] ]]
        then
                print -- "File ${file} not found "
        else
                print -- "File ${file} found"
        fi
done

Unfortunately all are being flagged up as 'not found' when I know there are some of the same filenames in both variables.

Thanks.

For lists you could do something like:

#!/usr/bin/ksh

A="1 2 3 4"
B="5 6 2 7"

for a in $A; do
        for b in $B; do
                (( $a == $b )) && print $a
        done
done

exit 0

For arrays you'll have to declare them with set -A ..... and cycle through their elements by incrementing the index. Though it would be most likely 2 loops in each other like the example above.

Update:
Here an example with an array without incrementing the indexes and comparing strings instead of numbers.
But when there is no need for indexes, maybe a list will be sufficient instead of arrays. But when having spaces in file names it might be easier to use them as array elements than in a list (depending how the separator IFS is defined and used in the list of course).

#!/usr/bin/ksh

set -A ARR1 1 2 3 4
set -A ARR2 5 6 2 7

for a in ${ARR1[*]}; do
        for b in ${ARR2[*]}; do
                [[ "$a" = "$b" ]] && print $a
        done
done

exit 0
1 Like

Thanks. The nested for loop works but if I want to output files that arent found as well I get repeated messages due to not matching to any of the array elements, how could I only output the filenames that arent found just once? I guess I could put them into another variable and then use the uniq command maybe?

for orig in ${origfilelist}
do
        for fail in ${failfiles}
        do
                if [[ ${orig} == ${fail} ]]
                then
                print -- "File ${orig} found "
else
print -- "File ${orig} not found"
                fi
        done
 
done

Thanks

p.s I though all variables were arrays?

---------- Post updated 30-01-13 at 09:17 AM ---------- Previous update was 29-01-13 at 01:11 PM ----------

Although I still would like the answer to the previous question I also need to know how to output the array elements onto different lines in a text file?

IFS solutions dont seem to be working.

 
OLDIFS="$IFS"; IFS=$'\n'
echo "${failagain
[*]}" >>"${reloadfiles}"/results.txt
IFS="$OLDIFS"
 

I have now been able to output to single lines by using another for loop.

 
for i in ${failagain
[*]}
do
echo $i >>"${reloadfiles}"/results.txt
done

Here is an example how you could cycle and compare array elements (example with integers) and print only those from array 1, which are not in array 2:

$ cat ./mach.ksh
#!/usr/bin/ksh

set -A ARR1 4 1 3 2
set -A ARR2 5 6 2 7 4 8

MAX=$((${#ARR2[*]}-1))

for a in ${ARR1[*]}; do
        COUNT=0
        set -A HITS
        for b in ${ARR2[*]}; do
                (( $a != $b )) && \
                HITS[$COUNT]=$a && \
                let COUNT+=1
        done
        (( ${#HITS[*]} != $MAX )) && \
        print ${HITS[0]}
        unset HITS
done

exit 0

$ ./mach.ksh
1
3

Somehow there is a blank line at the end. Didn't find where it comes from :wink:

Maybe other people have more efficient algorithm to do this which would be interessting for me too.

If you have 2 files with the lists of files you might want to compare, a grep -f file1 file2 or grep -vf file1 file2 might be more efficient than my example.