Skip to content

Instantly share code, notes, and snippets.

@CyberShadow
Last active April 3, 2020 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CyberShadow/551246534146f9c2ae1b84ef6226c714 to your computer and use it in GitHub Desktop.
Save CyberShadow/551246534146f9c2ae1b84ef6226c714 to your computer and use it in GitHub Desktop.
#!/bin/bash
# shellcheck disable=SC1003
set -eEuo pipefail
# Converts a list of wildcard patterns, as defined by glob(7) and used
# by e.g. GNU find for the -path switch, to a single regular
# expression.
function ShellPatternsToRegex() {
local patterns=("$@")
local regexps=()
local pattern
for pattern in "${patterns[@]}"
do
local regexp='^'
while [[ "$pattern" =~ ^([^][*?$\(\)*+.\\^{|]*)([][*?$\(\)*+.\\^{|}])(.*)$ ]] # split by glob special character
do
regexp=$regexp${BASH_REMATCH[1]}
pattern=${BASH_REMATCH[3]}
case "${BASH_REMATCH[2]}" in
'[')
if [[ "$pattern" =~ ^(!?)(\]?[^]]*\])(.*)$ ]]
then
regexp=$regexp'['
if [[ -n "${BASH_REMATCH[1]}" ]]
then
regexp=$regexp'^'
fi
regexp=$regexp${BASH_REMATCH[2]}
pattern=${BASH_REMATCH[3]}
else # '[' without matching ']'
regexp=$regexp'\['
fi
;;
'*')
regexp=$regexp'.*'
;;
'?')
regexp=$regexp'.'
;;
'^'|']')
regexp=$regexp'\'"${BASH_REMATCH[2]}"
;;
*)
regexp=$regexp'['"${BASH_REMATCH[2]}"']'
;;
esac
done
regexp=$regexp$pattern'$'
regexps+=("$regexp")
done
( IFS='|' ; echo "${regexps[*]}" )
}
: Test
ShellPatternsToRegex '*'
ShellPatternsToRegex 'a?c'
ShellPatternsToRegex 'a[b'
ShellPatternsToRegex 'a[b]c'
ShellPatternsToRegex 'a[!b]c'
ShellPatternsToRegex 'a[][]c'
ShellPatternsToRegex 'a[!][]c'
ShellPatternsToRegex 'a*' 'b*' 'c*'
ShellPatternsToRegex 'a.b'
ShellPatternsToRegex 'a(b)c'
ShellPatternsToRegex 'a^c'
ShellPatternsToRegex 'a.*c'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment