help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: help with pattern matching needed


From: Lawrence Velázquez
Subject: Re: help with pattern matching needed
Date: Tue, 11 Jan 2022 02:00:50 -0500
User-agent: Cyrus-JMAP/3.5.0-alpha0-4569-g891f756243-fm-20220111.001-g891f7562

On Tue, Jan 11, 2022, at 12:18 AM, Christoph Anton Mitterer wrote:
> So my understanding is that the quotes work the following way:
> First, ${bar} is expanded, to * and only then the quotes around that
> come into play.

It's the other way around.  First, the quotes work as usual -- e.g.
parameter expansions occur within double quotes but not within
single quotes.  Then, as previously discussed, the pattern matching
searches for the resulting characters literally, regardless of how
they were originally quoted.  Additionally, double quotes that
enclose the parameter expansion itself do not affect this.

For example:

    % cat ex1.sh; echo
    string='***$bar+++'
    bar=*

    printf '<%s>\n' "${string##*$bar}"
    printf '<%s>\n' "${string##*"$bar"}"
    printf '<%s>\n' "${string##*'$bar'}"

    % bash --posix ex1.sh
    <>
    <$bar+++>
    <+++>

In the first expansion, $bar is substituted into the pattern, but
since it isn't quoted, pattern-special characters in the result
remain special.  The resulting pattern is **, so the entire expansion
is deleted.

In the second expansion, $bar is substituted into the pattern, but
since it was quoted, the result is matched literally.  The pattern
is effectively *\*, so the portion of the expansion up to and
including the rightmost * is deleted.

In the third expansion, $bar is not substituted because it is within
single quotes.  The pattern is *$bar, so the portion of the expansion
up to and including the rightmost substring '$bar' is deleted.


> I tried for the cases when bar is either " or ' :
>
> $ bar="'"
> $ string="fo'o"
> $ echo "${string##*${bar}*}"
>
> $ echo "${string##*"${bar}"*}"
>
> $ echo "${string##*'${bar}'*}"
> fo'o
> $ 
> => I'd have expected the first 2, but the last one... shouldn't that
>    be effectively "${string##*'''*}"

No, the pattern is *${bar}*, which matches any string containing
the substring '${bar}'.


> $ bar='"'
> $ echo "${string##*${bar}*}"
> fo'o
> $ echo "${string##*"${bar}"*}"
> fo'o
> $ echo "${string##*'${bar}'*}"
> fo'o
> $ 
>
> => 1st and 3rd expected... 2nd, well kinda...

Your "string" variable contains neither " nor ${bar}, so none of
these patterns match anything.


> $ string='fo"o'
> $ echo "${string##*${bar}*}"
>
> $ echo "${string##*"${bar}"*}"
>
> $ echo "${string##*'${bar}'*}"
> fo"o
> $ 
> => 1st expected, but 2nd and 3rd are strange... I'd have expected their
>    results swapped

In the first and second expansions, $bar is substituted, so the
effective pattern is *"*, and the entire expansion is removed.

The "string" variable still does not contain the substring ${bar},
and the third pattern still doesn't match anything.


> At least it didn't seem as if the outer " around the ${} caused any
> harm.

Right.  You can think of the patterns as having a separate quoting
context, in a sense.


-- 
vq



reply via email to

[Prev in Thread] Current Thread [Next in Thread]