Wednesday, October 27, 2021

[SOLVED] Using parentheses to group expressions in case

Issue

I would like to group expressions with () in case, like so:

case a in
'*(a|b)*') printf '%s\n' 'something something';;
esac

This has not yielded any success though. I have also tried:

*(a|b)* *'('a|b')'* None of which I had success with.


Solution

This will be Bash specific:

You need to enable extglob and use this specific syntax

#!/usr/bin/env bash

shopt -s extglob

case "$1" in
*@(a|b)*) printf '%s\n' 'something something';;
esac

See man bash:

If the extglob shell option is enabled using the shopt builtin, several extended pattern matching operators are recognized. In the following description, a pattern-list is a list of one or more patterns separated by a |. Composite patterns may be formed using one or more of the following sub-patterns:

  • ?(pattern-list)
    Matches zero or one occurrence of the given patterns
  • *(pattern-list)
    Matches zero or more occurrences of the given patterns
  • +(pattern-list)
    Matches one or more occurrences of the given patterns
  • @(pattern-list)
    Matches one of the given patterns
  • !(pattern-list)
    Matches anything except one of the given patterns

Alternatively you can have the case continue execution with the next pattern's commands group, using a special ;& marker at end of the commands group.

This is NOT POSIX but handled by bash, ksh or zsh still:

#!/usr/bin/env ksh

case "$1" in
  *a*) ;& # Continue to next commands group
  *b*) printf '%s\n' 'something something';;
esac

And now, as that other guy pointed-out in a comment.

THE POSIX WAY:

#!/usr/bin/env sh

case "$1" in
  *a*|*b*) printf '%s\n' 'something something';;
esac


Answered By - Léa Gris