Why regex doesn't work in while loop's condition?

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Why regex doesn't work in while loop's condition?

JohnS
Hi, all!

Why next construction doesn't work?

read x; while [ "$x" != [abc] ]; do echo "Not a, b or c"; break; done

I tried many variants but can't make it work. Moreover I don't understand WHY it
doesn't work?!

Thanks!

Reply | Threaded
Open this post in threaded view
|

Re: Why regex doesn't work in while loop's condition?

Andreas Kusalananda Kähäri-4
On Fri, Sep 06, 2019 at 11:39:06PM +0500, JohnS wrote:

> Hi, all!
>
> Why next construction doesn't work?
>
> read x; while [ "$x" != [abc] ]; do echo "Not a, b or c"; break; done
>
> I tried many variants but can't make it work. Moreover I don't understand WHY it
> doesn't work?!
>
> Thanks!

The shells in the OpenBSD base system do not support matching regular
expressions with that syntax.  You may have been thinking of bash,

    while [[ ! $x =~ [abc] ]]; do ...; done

Or, in ksh,

    while [[ $x != [abc] ]]; do ...; done

Here however, [abc] is not a regular expression, but a filename globbing
pattern, and the test will test for equality rather than trying to match
a substring (as would be the case with a regular expression match).

Note that this test requries [[ ... ]] rather than [ ... ].  See the
ksh(1) manual.    

Reply | Threaded
Open this post in threaded view
|

Re: Why regex doesn't work in while loop's condition?

Andreas Kusalananda Kähäri-4
On Fri, Sep 06, 2019 at 08:55:10PM +0200, Andreas Kusalananda Kähäri wrote:

> On Fri, Sep 06, 2019 at 11:39:06PM +0500, JohnS wrote:
> > Hi, all!
> >
> > Why next construction doesn't work?
> >
> > read x; while [ "$x" != [abc] ]; do echo "Not a, b or c"; break; done
> >
> > I tried many variants but can't make it work. Moreover I don't understand WHY it
> > doesn't work?!
> >
> > Thanks!
>
> The shells in the OpenBSD base system do not support matching regular
> expressions with that syntax.  You may have been thinking of bash,
>
>     while [[ ! $x =~ [abc] ]]; do ...; done
>
> Or, in ksh,
>
>     while [[ $x != [abc] ]]; do ...; done
>
> Here however, [abc] is not a regular expression, but a filename globbing
> pattern, and the test will test for equality rather than trying to match
> a substring (as would be the case with a regular expression match).

"equality" was not quite what I meant. It would test for a match against
the whole of $x, as any globbing pattern would do, rather than a
substring of $x, as a regular expression would do. I.e., the bash code
above tests whether $x *contains* a, b, or c, while the ksh code beneath
it tests whether $x *is* a, b or c (and then the result of the test is
negated).

>
> Note that this test requries [[ ... ]] rather than [ ... ].  See the
> ksh(1) manual.    

Reply | Threaded
Open this post in threaded view
|

Re: Why regex doesn't work in while loop's condition?

Christian Weisgerber
In reply to this post by Andreas Kusalananda Kähäri-4
On 2019-09-06, Andreas Kusalananda Kähäri <[hidden email]> wrote:

>> read x; while [ "$x" != [abc] ]; do echo "Not a, b or c"; break; done
>
> The shells in the OpenBSD base system do not support matching regular
> expressions with that syntax.  You may have been thinking of bash,

Just to head off crazy rumors: bash doesn't either.

--
Christian "naddy" Weisgerber                          [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Why regex doesn't work in while loop's condition?

Theo de Raadt-2
Christian Weisgerber <[hidden email]> wrote:

> On 2019-09-06, Andreas Kusalananda Kähäri <[hidden email]> wrote:
>
> >> read x; while [ "$x" != [abc] ]; do echo "Not a, b or c"; break; done
> >
> > The shells in the OpenBSD base system do not support matching regular
> > expressions with that syntax.  You may have been thinking of bash,
>
> Just to head off crazy rumors: bash doesn't either.

Doesn't bash perform this task by invisibly calling out to perl?

Reply | Threaded
Open this post in threaded view
|

Re: Why regex doesn't work in while loop's condition?

Raul Miller
In reply to this post by JohnS
On Fri, Sep 6, 2019 at 2:40 PM JohnS <[hidden email]> wrote:
> Why next construction doesn't work?
>
> read x; while [ "$x" != [abc] ]; do echo "Not a, b or c"; break; done

People have been focusing on the syntax of arguments for test (the
left bracket operation), but there's no 'next' here.

You are reading x just once and then going into a loop. That's almost
certainly not what you want to do.

You might want to be doing something like this:

       while read x; ! echo $x | egrep -q '[abc]'; do echo 'Not a, b or c'; done

But, given how non-functional your code example was, and how
non-descriptive your surrounding text was, it's kind of hard to
tell...

That said, good luck,

--
Raul

Reply | Threaded
Open this post in threaded view
|

Re: Why regex doesn't work in while loop's condition?

Andreas Kusalananda Kähäri-4
In reply to this post by Theo de Raadt-2
On Fri, Sep 06, 2019 at 02:38:18PM -0600, Theo de Raadt wrote:

> Christian Weisgerber <[hidden email]> wrote:
>
> > On 2019-09-06, Andreas Kusalananda Kähäri <[hidden email]> wrote:
> >
> > >> read x; while [ "$x" != [abc] ]; do echo "Not a, b or c"; break; done
> > >
> > > The shells in the OpenBSD base system do not support matching regular
> > > expressions with that syntax.  You may have been thinking of bash,
> >
> > Just to head off crazy rumors: bash doesn't either.
>
> Doesn't bash perform this task by invisibly calling out to perl?

You're thinking of zsh.

Reply | Threaded
Open this post in threaded view
|

Re: Why regex doesn't work in while loop's condition?

Theo de Raadt-2
Andreas Kusalananda Kähäri <[hidden email]> wrote:

> On Fri, Sep 06, 2019 at 02:38:18PM -0600, Theo de Raadt wrote:
> > Christian Weisgerber <[hidden email]> wrote:
> >
> > > On 2019-09-06, Andreas Kusalananda Kähäri <[hidden email]> wrote:
> > >
> > > >> read x; while [ "$x" != [abc] ]; do echo "Not a, b or c"; break; done
> > > >
> > > > The shells in the OpenBSD base system do not support matching regular
> > > > expressions with that syntax.  You may have been thinking of bash,
> > >
> > > Just to head off crazy rumors: bash doesn't either.
> >
> > Doesn't bash perform this task by invisibly calling out to perl?
>
> You're thinking of zsh.

No I'm thinking it is all crazy.

Reply | Threaded
Open this post in threaded view
|

Re: Why regex doesn't work in while loop's condition?

gwes-2


On 9/6/19 5:27 PM, Theo de Raadt wrote:

> Andreas Kusalananda Kähäri <[hidden email]> wrote:
>
>> On Fri, Sep 06, 2019 at 02:38:18PM -0600, Theo de Raadt wrote:
>>> Christian Weisgerber <[hidden email]> wrote:
>>>
>>>> On 2019-09-06, Andreas Kusalananda Kähäri <[hidden email]> wrote:
>>>>
>>>>>> read x; while [ "$x" != [abc] ]; do echo "Not a, b or c"; break; done
>>>>> The shells in the OpenBSD base system do not support matching regular
>>>>> expressions with that syntax.  You may have been thinking of bash,
>>>> Just to head off crazy rumors: bash doesn't either.
>>> Doesn't bash perform this task by invisibly calling out to perl?
>> You're thinking of zsh.
> No I'm thinking it is all crazy.
>
CRAZY=true
[ is not [[
man ksh
[[ expression ]]
      Similar to the test and [ ... ] commands (described later), with
      the following exceptions:
...
    The second operand of the ‘!=’ and ‘=’ expressions are
          patterns (e.g. the comparison [[ foobar = f*r ]]
          succeeds).
....

X=a
if [[ "$X" == [abc] ]] ; then echo yes ; fi
prints yes
ksh is in base and is often a user's login shell