On Fri, 24 Feb 2012, Jesper Nygårds wrote: > Date: Thu, 23 Feb 2012 23:11:29 > From: Jesper Nygårds > To: zsh-users@zsh.org > Subject: Filtering an array > > I am scratching my head over getting something seemingly simple to work. > > I have written this function: > > findfiles() { > local myfiles myarg > myfiles=( **/*$1* ) > shift > for myarg in $@; do > myfiles=${(M)myfiles:#*$myarg*} > done > print $myfiles > } jesper this is my version of your function. the biggest difference i see between your function and my version (with regard to intent and disregarding coding errors), is the initial expansion of ${myfiles}. file selection in both versions is done by pattern matching, so i did not use the same initial file list loading as yours myfiles=( **/*$1* ) to cause any subsetting; that step struck me as unneccessary. also, your version redefines ${myfiles} in every instance of the for loop; this never accummulates the pattern matches which is what i thought was your objective. if i misunderstood your requirements, i apologize. the function shown here does give a correct list of unique files matching the pattern[s] given on the invocation line. usage: findfiles starting_sub_dir pat1 [pat2...] findfiles(){ # parameter declarations. typeset -a pats allfiles typeset -aU selection local srcdir pat # argument parsing and checking. srcdir=${1} if [[ ! -d ${srcdir} ]] then # bomb. return 1 fi shift # patterns for which to search. pats=( $@ ) # get all files (only files, including dot files) in specified # source directory. allfiles=( ${srcdir}/**/*(D,.) ) # initialize the collection. selection=() # do the subsetting and collecting. for pat in ${pats} do selection=( ${selection} # append any additional matches. ${(M)allfiles:#*${pat}*} ) done # report the results. print -l ${selection} # clean up. unset srcdir pat pats allfiles selection }