Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: array filtering



Try this? Works for any value of $1 except when 1=""

arr=( ${(M)arr%%*/[^/]#${1}[^/]#/} )

Full example:

#!/usr/bin/env zsh
# array-filtering.zsh

setopt localoptions extended_glob

test_dir_array_submatch() {
  local -a arr=( /dira/${1}/dirb/ /dirc/A${1}B/dird/ /dire/${1}/ /dirf/C${1}D/ )

  # works for all values of $1 except ""
  print -- ${(M)arr%%*/[^/]#${1}[^/]#/}
}

test_dir_array_submatch Z
test_dir_array_submatch AAA
test_dir_array_submatch AB
test_dir_array_submatch 1
test_dir_array_submatch ""

Outputs:

/dire/Z/ /dirf/CZD/
/dire/AAA/ /dirf/CAAAD/
/dire/AB/ /dirf/CABD/
/dire/1/ /dirf/C1D/
/dira//dirb/ /dirc/AB/dird/ /dire// /dirf/CD/


- Rick

Thanks,

Rick


On Sun, Jun 9, 2024 at 10:50 AM Ray Andrews <rayandrews@xxxxxxxxxxx> wrote:
I'm getting better at various filterings but this one eludes me:

arr=( /dira/${1}/dirb/ /dirc/A${1}B/dird/ /dire/${1}/ /dirf/C${1}D/ )

... it's pretty fussy, but I want to filter out the first and second elements.  The test is that for a list of directories, for an element to be retained the argument ($1) may be an exact directory name, or a partial directory name, but it must be the last directory.  Not sure if I'm expressing that correctly. No subdirectories may follow the matched name, be it exact or partial.


arr=( ${(M)arr:#(#i)*/$1/} )

... that works if the name matches exactly but:

arr=( ${(M)arr:#(#i)*/*$1*/} )

... that ends up too broad, $1 matches anywhere irrespective of slashes.

arr=( ${(M)arr:#(#i)*/*$1[^/]*/} )

... ends up too narrow, it catches a completed name but misses the exact match which puzzles me because I'd read that: '... anything except a slash, any number of characters or none' -- which should find the exact match: ' [^/]* ' should simply be empty, no?




Messages sorted by: Reverse Date, Date, Thread, Author