Here's my suggestion, removing single-letter variables and changing the location of the archive for consistency's sake:
#!/system/bin/sh -xv
cd "$PWD/../WorkingDir"
compress() {
# Detect only known dir names, convert slash to underscore
local arch="$(echo $1 | sed -rne '/320\/(light|dark)/s@/@_@gp')"
# Set a default value to the variable
: ${arch:=file}
# Only create a ZIP archive if not present in the parent directory
# Note $PWD is evaluated *before* cd
[ -f "${arch}.zip" ] || ( cd -- $1 && zip -0rq "${PWD}/${arch}.zip ." )
}
for dir in */*/; do
compress $dir
done
Just change the sed line to add what I called "well-known directory names".
EDIT: Adding a few explanations, as per OP request.
The script does verify conditions prior to zipping directories each time a new directory is found by the for loop. Variables have also been eliminated. Let's dissect the code.
The main loop
cd "$PWD/../WorkingDir"
for dir in */*/; do # Ensures to select only directories
compress $dir # compress runs some checks prior to compressing
done
There is indeed not much more to say about it.
The compress routine
local arch="$(echo $1 | sed -rne '/320\/(light|dark)/s@/@_@gp')"
$1 is the argument passed to compressed, i.e. the directory to check and compress. What sed does first ('/320\/(light|dark)/') is check whether the path is of the form
320/light
320/dark
and returns the path with the slash converted to an underscore: 's@/@_@g'. Using the at sign as a separator for readability to avoid escaping the slash. Other valid notations are 's:/:_:g' or 's#/#_#g' or the classical 's/\//_/g'. Note how the slash to transform is escaped with an anti slash. I find the latter form less readable though.
The trailing p works together with sed -n; the latter option in this particular case means «don't echo anything unless told to by p whenever a match (i.e. in the enclosing slashes) is found». Therefore arch will contain a path with the slash transformed into an underscore if and only if the regular expression 320\/(light|dark) is found in the path. Otherwise it will echo nothing, making arch a blank variable.
Option -r is a convenient way to tell sed to use canonical regular expressions, more readable. Otherwise you would need to escape the parenthesis and pipe characters. I find '/320\/(light|dark)/s@/@_@gp' more readable than '/320\/\(light\|dark\)/s@/@_@gp' or '/320\/\(light\|dark\)/s/\//_/gp'.
: ${arch:=file}
This line sets arch to its default value "file" if it is blank. The weird construction is required because ${arch:=file} alone triggers a syntax error. The colon tells the shell to do nothing (:) but assign arch a value if it is blank.
[ -f "${arch}.zip" ] || ( cd -- $1 && zip -0rq "${PWD}/${arch}.zip ." )
Here I used -f instead of -e because the former also checks for zero-length files. The test will succeed only if a ZIP archive exists and has a non zero length.
If there's no archive file in the parent (or the script's current) directory or if its size is null, then the script spawns a sub-shell that changes to the directory passed as an argument to compress and zips its content. Note that variables $1 and $PWD are evaluated before the sub-shell executes its instructions, i.e. $PWD is equal to the parent directory $Z in your initial version.
Expanding the filter
You can act upon sed the following way:
sed -rne '/320\/(light|dark|play)/s@/@_@gp'
to check directory names such as
320/light
320/dark
320/play
You may also consider /(320|480|540)\/(light|dark|play)/, which gives you 9 combinations, or a more generic form /[0-9]+\/(light|dark|play)/ (any number followed by a slash and one of "light", "dark" and "play") or even /[0-9]+\/\w+/ (any number followed by a slash and a word aka [A-Za-z0-9_]+). It all depends how strict or broad you want the filter to be.
forloop, consequently all compressed files will have that very same name. Could you add examples of what you'd wished?//or/as shells properly eliminate the dupe slash evaluating expressions.