Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Belaboring substitution syntax
On Tue, Nov 15, 2022 at 6:18 AM Ray Andrews <rayandrews@xxxxxxxxxxx> wrote:
>
> I sorta get that '[@]' is saying: "process this array line by line" thus preserving array indexes. I'm not sure about the quotes.
This follows the same rules as $@. If you write "${array[@]}" with
the quotes, you get each element of the array separately quoted. This
often doesn't matter in zsh but always matters in other shells or when
SH_WORD_SPLIT is enabled in zsh.
BTW you need to stop thinking of these as "lines" -- line breaks have
nothing to do with it.
Conversely if you write "${array}" or ${array[*]}" either one with the
quotes, you get the entire array joined into a single string.
> and sometimes the quotes seem to protect stuff from expansion or interpretation:
Quotes ALWAYS protect SOMETHING from expansion or interpretation,
unless you start throwing other things in there such as eval. WHAT is
protected differs: Double quotes allow ${param} and $(process) and
$((math)) replacements but protect syntax tokens and glob patterns and
whitespace; single quotes protect pretty much everything.
> In my case, leaving the quotes out doesn't *seem* to matter but I know it would bite me eventually. When would it bite me?
In the specific example in this thread, zsh's default array behavior
(no_SH_WORD_SPLIT) is sufficient, but if you later enclose that or a
similar construct in a deeper context, yes, you might be bitten.
> Do we not have an operator that says (in English): If string A is a substring of B, then return B, else return nothing.
Your trouble is the definition of "nothing." ${B:#*A*} does that, but
in your example here, you don't actually want "nothing", you want "the
empty string" which is still something.
In fact the example in question is "if A is NOT a substring of B then
return B, else return the empty string."
So we have this:
Do a replacement on every element of $cc is ${cc[@]/...}
Replacement must start at beginning of element ${cc[@]/#...}
Replacement must also end at end of element ${cc[@]/#%...}
Use $zsh_case as a pattern is $~zsh_case
Match that pattern anywhere with $filter is *$~zsh_case${filter}*
Match NOT that whole pattern is ^*$~zsh_case${filter}*
Put it all together: ${cc[@]/#%^*$~zsh_case${filter}*
Replace all that with the empty string is just close the brace
${cc[@]/#%^*$~zsh_case${filter}*}
... and then the double-quotes for safety.
About the only thing your magical operator could remove is putting
*...* around the pattern to mean "is a substring".
Messages sorted by:
Reverse Date,
Date,
Thread,
Author