Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Within a bash script, I am building two dynamic arrays. And I want to construct another array with difference of two.

Example:

array1=("aa-1234|safsf|sfsfs" "aa-2345|sfsfs|n0sfm" "aa-0890|ssfsf|sfss" "aa-8097|fsfsf|fsfs" "bb-1234|xvxx|xvxv" "cc-1234|jmsf|sfsfs" "cc-1235|xvxv|xvxv")
array2=(aa-1234 aa-8097)

array1 elements are long entries with | as a delimiter in each.

Now I want to construct an array3, whose elements are all of array1 except those matching in array2.

I tried a for loop to skip through elements. However array1 being a long one, it too much time. I'm looking for a more efficient way.

share|improve this question

1 Answer 1

up vote 2 down vote accepted

I would construct a regular expression out of the 2nd array, and then compare the elements of the 1st array against it:

$ re=$(IFS='|'; echo "^(${array2[*]})\|")
$ echo "$re"
^(aa-1234|aa-8097)\|
$ for elem in "${array1[@]}"; do if [[ $elem =~ $re ]]; then array3+=("$elem"); fi; done
$ printf "%s\n" "${array3[@]}"
aa-1234|safsf|sfsfs
aa-8097|fsfsf|fsfs

If the arrays are much larger than shown, I'd farm the exercise out to grep

$ grep -Ff <(printf "%s\n" "${array2[@]}") <(printf "%s\n" "${array1[@]}")
aa-1234|safsf|sfsfs
aa-8097|fsfsf|fsfs
share|improve this answer
    
Glenn, Thanks for the solution. This works best for Intersection of arrays. However I am looking for entries of array1 excluding matching entries of array2 –  sudobash Nov 21 '14 at 1:20
1  
So just negate it: if ! [[ $elem =~ $re ]] or grep -v -Ff ... –  glenn jackman Nov 21 '14 at 2:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.