Friday, March 5, 2010

Regular expression in condition statement, the ksh and bash examples

Ksh has better regular expression support than bash
bash has = to support Basic regular expressions and its result is exact match
bash has =~ to support Extended regular expressions ( Metacharacter ? + and character classes like [:alnum:] ) and its result is partial match

The followings use "if statement" as examples

##Example 1 :Match string host1 or host2

#!/bin/ksh
if [[ "$1" = host[12] ]];then echo Match; fi
#!/bin/bash 
if [[ "$1" = host[12] ]]; then echo match ;fi
#!/bin/bash
#Note the ^ $ due to  partial match nature of =~
if [[ "$1" =~ ^host[12]$ ]]; then echo match ;fi
##Example 2 :Match string linux or solaris
#!/bin/ksh
if [[ "$1" = @(linux|solaris) ]];then echo Match; fi
# bash's = doesn’t support |, You have to use the traditional way to join with –o
#!/bin/bash
if [[ "$1" =~ "^linux$|^solaris$" ]]; then echo match ;fi
##Example 3 :Match any three digits

#!/bin/ksh
if [[ "$1" = {3}(\d) ]];then echo Match; fi

#!/bin/bash
if [[ "$1" = [0-9][0-9][0-9] ]]; then echo match ;fi
#!/bin/bash
if [[ "$1" =~ "^[0-9]{3}$" ]]; then echo match ;fi
#Example 4 : Match liNux or soLaRis case insensitive match

#!/bin/ksh
if [[ "$1" = @(~(i:linux|solaris)) ]];then echo Match; fi

#!/bin/bash
shopt -s nocasematch
if [[ "$1" =~ "^solaris$|^linux$" ]]; then echo match ;fi
Finally, bash support similar syntax to ksh with extglob option enabled.

#!/bin/bash
shopt -s extglob
shopt -s nocasematch
if [[ "$1" = @(solaris|linux) ]]; then echo match ;fi

#reference
man ksh

A pattern-list is a list of one or more patterns separated from each other with a & or â. A & signifies that all patterns must be matched whereas
â requires that only one pattern be matched. Composite patterns can be formed with one or more of the following sub-patterns:
?(pattern-list)
Optionally matches any one 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.
{n}(pattern-list)
Matches n occurrences of the given patterns.
{m,n}(pattern-list)
Matches from m to n occurrences of the given patterns. If m is omitted, 0 will be used. If n is omitted at least m occurrences
will be matched.
@(pattern-list)
Matches exactly one of the given patterns.
!(pattern-list)
Matches anything except one of the given patterns.

By default, each pattern, or sub-pattern will match the longest string possible consistent with generating the longest overall match. If more
than one match is possible, the one starting closest to the beginning of the string will be chosen. However, for each of the above compound patâ
terns a - can be inserted in front of the ( to cause the shortest match to the specified pattern-list to be used.
When pattern-list is contained within parenthesis, the backslash character \ is treated specially even when inside a character class. All ANSI-C
character escapes are recognized and match the specified character. In addition the following escape sequences are recognized:
\d Matches any charcter in the digit class.
\D Matches any charcter not in the digit class.
\s Matches any charcter in the space class.
\S Matches any charcter not in the space class.
\w Matches any charcter in the word class.
\W Matches any charcter not in the word class.
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 followâ
ing 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

4 comments:

  1. Good Job, I really like your neat posts.

    ReplyDelete
  2. Your post is the first Google result that documents this underused ksh operator. Thanks man!

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. For regular expressions, you should refer to `man grep`.

    The ?(pattern-list), *(pattern-list), etc. examples you extracted from `man ksh` refer to the the topic of File Name Generation. That's different cook!

    ReplyDelete