Bash Regular Expression -- Can't seem to match any of \s \S \d \D \w \W etc
Perhaps \S and \s are not supported, or that you cannot place them around [ ]
. Try to use the following regex instead:
^Disk[[:space:]]+/dev[^[:space:]]+:[[:space:]]+[^[:space:]]+
EDIT
It seems like you actually want to get the matching fields. I simplified the script to this for that.
#!/bin/bash
regex='^Disk[[:space:]]+(/dev[^[:space:]]+):[[:space:]]+(.*)'
while read line; do
[[ $line =~ $regex ]] && echo "${BASH_REMATCH[1]} matches ${BASH_REMATCH[2]}."
done < disks.txt
Produces:
/dev/sda matches 42.9GB.
/dev/sdb matches 42.9GB.
Because this is a common FAQ, let me list a few constructs which are not supported in Bash, and how to work around them, where there is a simple workaround.
There are multiple dialects of regular expressions in common use. The one supported by Bash is a variant of Extended Regular Expressions. This is different from e.g. what many online regex testers support, which is often the more modern Perl 5 / PCRE variant.
- Bash doesn't support
\d
\D
\s
\S
\w
\W
-- these can be replaced with POSIX character class equivalents[[:digit:]]
,[^[:digit:]]
,[[:space:]]
,[^[:space:]]
,[_[:alnum:]]
, and[^_[:alnum:]]
, respectively. (Notice the last case, where the[:alnum:]
POSIX character class is augmented with underscore to be exactly equivalent to the Perl\w
shorthand.) - Bash doesn't support non-greedy matching. You can sometimes replace
a.*?b
with something likea[^ab]*b
to get a similar effect in practice, though the two are not exactly equivalent. - Bash doesn't support non-capturing parentheses
(?:...)
. In the trivial case, just use capturing parentheses(...)
instead; though of course, if you use capture groups and/or backreferences, this will renumber your capture groups. - Bash doesn't support lookarounds like
(?<=before)
or(?!after)
and in fact anything with(?
is a Perl extension. There is no simple general workaround for these, though you can often rephrase your problem into one where lookarounds can be avoided.
from man bash
An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is con‐ sidered an extended regular expression and matched accordingly (as in regex(3)).
ERE doesn't support look-ahead/behind. However you have them in your code ((?!Disk)
).
That's why your regex won't do match as you expected.