Reputation: 821
I thought I had a good regex line below that works with tests I did in Regexbuddy, but doesn't seem to work in bash.
I need someone with much better knowledge of regex than me to help me out. ;)
The point is to do a basic test as to whether a string contains a remote host for rsync. So we're testing for something valid like username@host:/ or username@host:~/ (and I also assume ./ ?) ...
#!/bin/bash
test="foo@bar:/here/path/"
regex='^([\w-_.]*)@([\w-_.:]*):[~./]'
if [[ "${test}" =~ "${regex}" ]]; then
echo "yes, remote host"
else
echo "no, local"
fi
# filter for remote host by regex
# ^ begin at start of line, ( [ match underscore, word & number chars, dashes, fullstops ] in * repetition ) until first @ and then ( [ match underscore, word & number chars, dashes, fullstops, and colons] in * repetition ) until : and then at least [ ~ or . or / )
# so [email protected]:/path/ will match
# [email protected]:~/path/ will match
# blah123.user@2001:db8:85a3:8d3:1319:8a2e:370:7348:./path/ will match
# user@wherever:path/ will not, and /[email protected]:with/a/slash will not match
# etc
Any ideas?
Upvotes: 2
Views: 375
Reputation: 1059
Bash doesn't support character classes like \w
, have a look here https://tldp.org/LDP/abs/html/x17129.html section POSIX Character Classes
In your case try replacing \w
with [:alnum:]
and you have to remove the quotes on the right side of =~
.
I modified it a bit but this works for me:
[[ "foo@bar:/here/path/" =~ ^[-_\.[:alnum:]]+@[-_\.[:alnum:]]+:[~./] ]] && \
echo "Remote" || \
echo "Local"
Upvotes: 1
Reputation: 627103
There are several issues:
$regex
variable should not be quoted after =~
, or non-regex string matching gets enabled\w
should not be used, use [:alnum:]
POSIX character class instead, that matches letters and digits-
in bracket expressions should be the first or last character to be correctly parsed as a hyphen.I'd also use +
(1 or more) quantifier instead of *
in the pattern to enforce at least one char before and after @
.
You can use
test="foo@bar:/here/path/"
regex='^([[:alnum:]_.-]+)@([[:alnum:]_.:-]+):[~./]'
if [[ "$test" =~ $regex ]]; then
echo "yes, remote host"
else
echo "no, local"
fi
See Bash demo.
Upvotes: 4