Skip to content

bash regexp

ghdrako edited this page Mar 29, 2024 · 8 revisions

Globbing vs. Regular Expressions:

Bash supports both globbing (pattern matching with '*' and ?,+,!) and regular expressions.

Pattern Matching in Bash

[[ string =~ regex ]]
input="Hello123"
if [[ "$input" =~ ^[A-Za-z]+$ ]]; then
echo "Input contains only letters."
fi
if ! [[ "${filename}" =~ [^\.]+\.html$ ]]; then
  echo -e "\n\"${filename}\": must have .html extension" >&2
  exit 42
fi

Matching Numbers

number="12345"
if [[ "$number" =~ ^[0-9]+$ ]]; then
  echo "Input is a valid number."
fi

Matching Email Addresses:

email="user@example.com"
if [[ "$email" =~ ^([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+)\.([a-zA-Z]{2,})$ ]]; then
  echo "Valid email address."
fi

Capture Groups:

Use parentheses () to capture parts of the matched text.

log_entry="Error: File not found (file.txt)"
if [[ "$log_entry" =~ Error: (.+) ]]; then
error_message="${BASH_REMATCH[1]}"
echo "Error message: $error_message"
fi

Case-Insensitive Matching:

  • Option: Use the nocasematch option for case-insensitive matching.
shopt -s nocasematch
input="AbCdEf"
if [[ "$input" =~ ^abcd ]]; then
  echo "Matched case-insensitively."
fi
shopt -u nocasematch Disable nocasematch option

BASH_REMATCH Array

[[ "abcdef" =~ (b)(.)(d)e ]]

# Now:
#   BASH_REMATCH[0]=bcde
#   BASH_REMATCH[1]=b
#   BASH_REMATCH[2]=c
#   BASH_REMATCH[3]=d 
# 
[[ "/home/jcdusse/index.html" =~ ^(.*)/(.*)\.(.*)$ ]]; echo
${BASH_REMATCH[@]}

# Now:
#   BASH_REMATCH[0]=/home/jcdusse/index.html
#   BASH_REMATCH[1]=/home/jcdusse
#   BASH_REMATCH[2]=index
#   BASH_REMATCH[3]=html

Extract the base filename

if [[ "abc/def/test.html" =~ .*/(.+)\..* ]]; then
  echo "${BASH_REMATCH[1]}"
fi
# outputs "test"

Extract the value of an XML element attribute

line='<something att1="value1" />'
if [[ "${line}" =~ att1=\"([^\"]*)\" ]]; then
  echo "${BASH_REMATCH[1]}"
fi

Extract application version

extract_app_version(){ $1 =~ ([0-9]+)(- local major_version="${BASH_REMATCH[1]}" local minor_version="${BASH_REMATCH[3]}" local patch_version="${BASH_REMATCH[5]}"

echo "$major_version $minor_version $patch_version"

}


str='release-2.15-5'; re='[0-9]+.[0-9]+'; if $str =~ $re; then echo "${BASH_REMATCH[0]}"; fi;

Test

Clone this wiki locally