Search code examples
arraysstringbashshstring-comparison

Check an array of strings against another array - Bash


I have two lists.

I have to check if there is a tar.gz which name contains a substring like aa or ab and so on. I'm using this little function: How do you tell if a string contains another string in POSIX sh?

local=(aa ab ac ad ae)
remote=(ab.tar.gz ac.tar.gz ad.tar.gz ae.tar.gz af.tar.gz)

contains() { test -n "$1" || test -z "$2" && test -z "${1##*"$2"*}"; }
for le in "${local[@]}"; do
    for re in "${remote[@]}"; do
        contains "$re" "$le" && to_dl+=("$re")
    done
done

This works well for me, but I need a second list, which contains the elements of the local list, that don't have a match in the remote list.


Solution

  • Small modification to OP's current code:

    local=(aa ab ac ad ae)
    remote=(ab.tar.gz ac.tar.gz ad.tar.gz ae.tar.gz af.tar.gz)
    
    unset to_dl not_there           # or: to_dl=() not_there=()
    
    contains() { test -n "$1" || test -z "$2" && test -z "${1##*"$2"*}"; }
    
    for le in "${local[@]}"
    do
        for re in "${remote[@]}"
        do
            contains "$re" "$le" && { to_dl+=("$re"); continue 2; }
        done
        not_there+=("$le")
    done
    

    Where:

    • continue 2 - if we find a match then skip to the next substring (le) in the list
    • not_there+=("$le") - if inner loop finds no matches then save the substring in a different array

    Results:

    $ typeset -p to_dl not_there
    declare -a to_dl=([0]="ab.tar.gz" [1]="ac.tar.gz" [2]="ad.tar.gz" [3]="ae.tar.gz")
    declare -a not_there=([0]="aa")