say have arrays
a1=(cats,cats.in,catses,dogs,dogs.in,dogses) a2=(cats.in,dogs.in)
i want remove a1 matches strings in a2 after removing ".in" , in addition ones match completely(including ".in").
so a1, want remove cats, cats.in, dogs, dogs.in, not catses or dogses.
i think i'll have in 2 steps. found how cut ".in" away:
for elem in "${a2[@]}" ; var="${elem}" len="${#var}" pref=${var:0:len-3} done
^ gives me "cats" , "dogs"
what command need add loop remove each elem a1?
seems me easiest way solve nested for
loops:
#!/usr/bin/env bash a1=(cats cats.in catses dogs dogs.in dogses) a2=(cats.in dogs.in) x in "${!a1[@]}"; # step through a1 index y in "${a2[@]}"; # step through a2 content if [[ "${a1[x]}" = "$y" || "${a1[x]}" = "${y%.in}" ]]; unset a1[x] fi done done declare -p a1
but depending on actual data, following might better, using 2 separate loops instead of nesting.
#!/usr/bin/env bash a1=(cats cats.in catses dogs dogs.in dogses) a2=(cats.in dogs.in) # flip "a2" array "b", stripping ".in" go... declare -a b=() x in "${!a2[@]}"; b[${a2[x]%.in}]="$x" done # check existence of stripped version of array content # index of associative array created above. x in "${!a1[@]}"; [[ -n "${b[${a1[x]%.in}]}" ]] && unset a1[$x] a1[${x%.in}] done declare -p a1
the advantage here instead of looping through of a2
each item in a1
, loop once on each array. down sides might depend on data. example, if contents of a2
large, might hit memory limits. of course, can't know included in question; solution works data provided.
note: solution depends on associative array, feature introduced bash in version 4. if you're running old version of bash, might time upgrade. :)
Comments
Post a Comment