Bash Regex Matching
Bash's =~ operator enables regex matching within [[ ]] conditionals.
Advantage over grep/rg: Better performance for small data - avoids process spawning overhead.
Syntax
if [[ $string =~ regex_pattern ]]; then
# Match found
fi
Key Points
Regex Type: POSIX Extended Regular Expressions (ERE)
Not Supported: GNU extensions (\b, \s, \d)
Captures: Stored in BASH_REMATCH array
[0]= full match[1],[2]... = capture groups
Quoting: Never quote the regex
[[ $str =~ ^[0-9]+$ ]] # ✓ Works
[[ $str =~ "^[0-9]+$" ]] # ✗ Treated as literal
POSIX Character Classes
[[:digit:]] # Instead of \d
[[:space:]] # Instead of \s
[[:alnum:]] # Alphanumeric
[[:alpha:]] # Letters only
Examples (Increasing Difficulty)
# 1. Exact match
[[ "hello" =~ ^hello$ ]]
# Matches exact string "hello"
# 2. Contains pattern
[[ "test123" =~ [0-9] ]]
# Checks if string contains any digit
# 3. One or more digits (+)
[[ "42" =~ ^[0-9]+$ ]]
# Matches strings with only digits (at least one)
# 4. Zero or more characters (*)
[[ "v1.2" =~ ^v[0-9]+\.[0-9]*$ ]]
# Matches "v1.2", "v1.", "v123.456" (optional digits after dot)
# 5. Optional pattern (?)
[[ "color" =~ ^colou?r$ ]]
# Matches both "color" and "colour"
# 6. File extension check
[[ "script.sh" =~ \.(sh|bash)$ ]]
# Matches files ending in .sh or .bash
# 7. Extract with captures
version="v2.4.1-beta"
[[ $version =~ ^v([0-9]+)\.([0-9]+)(\.([0-9]+))?(-(.+))?$ ]]
# Captures: major=2, minor=4, patch=1, tag=beta
# 8. IP address validation
ip="192.168.1.1"
[[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]
# Basic IP format check (doesn't validate ranges)
# 9. Parse log entry
log="2024-01-15 14:30:22 ERROR: Connection failed"
regex="^([0-9-]+) ([0-9:]+) ([A-Z]+): (.*)$"
[[ $log =~ $regex ]]
# Captures: date, time, level, message
Quantifiers:
*= Zero or more+= One or more?= Zero or one{n,m}= Between n and m occurrences