Search code examples
regexlinuxshelldash-shell

Check for substring in Shell without Bashisms


I'm trying to write a shell script, and in it I have to look for the presence of -32 in a string. Unfortunately I have to do it without using any bashisms as it has to run on computers running Dash.

I tried case ${1+"$@"} in *-32*);; but that will pick up something like -321. Is there a way to use a regex or something to look for just that flag? It can have other flags around it separated by spaces in the string.

I think the regex I would need looks for -32 with either a space or end of line after. -32(\s|$)

I'm pretty new to regexes so I'm not sure if that is the best way to do it. Any help would be appreciated!

Thanks!


Solution

  • You can use grep with word boundary:

    grep -E '-32\b' FILE
    

    \b matches at a 'word boundary' = the location between an alphanumeric character and a non-alphanumeric character.

    In the default locale, an 'alphanumeric character' (as the term is used above) means any character that is matched by the character class [a-zA-Z0-9_] (i.e. any number, any of the letters A–Z and underscore).

    In an analogous way \B matches wherever there is not a word boundary (i.e. any location where the characters on either side of it are of the same type, either both alphanumeric characters, or both non-alphanumeric).

    So if you wanted to make sure that the minus sign must be preceded by a non-alphanumeric character (e.g. space), as well, you would write the following:

    grep -E '\B-32\b' FILE
    

    This will match xx -32 xx (with a space before the minus) but not xx-32 xx (without the space). Since space and minus are both non-alphanumeric \B will match between them, but \b will not.

    If you wanted to make sure that the minus sign is preceded by a alphanumeric character instead, you would write the following:

    grep -E '\b-32\b' FILE
    

    Which matches e.g. x-32 x (without the space), but not x -32 x (with a space before the minus).