2

So, in my script, I have to decide whether one of the parameters is a valid email address. I was trying, but it failed.

if $maddr="^.$*\(@\)\(*\)\(.\)\(??*\)"

then
...

It's meant to mean: at least 1 character followed by @ followed by anything followed by a dot and followed by something, which has at least 2 characters.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
Wanderer
  • 649

2 Answers2

4

The Unix tool to match a string against a regexp is expr:

if expr "$maddr" : '..*@.*\...' > /dev/null; then...

(note that expr regexps are implicitly anchored at the beginning)

Though in this case, simple shell pattern matching would be enough:

case $maddr in
  ?*@*.??*) ...
esac

Note that some shells like zsh, ksh93 and bash have builtin regexp matching operators as an extension above the standard sh syntax, but the syntax varies slightly across those.

pattern='.@.*\...'
if [[ $maddr =~ $pattern ]]; then...

Should work across all three.

(note that those patterns don't guarantee a valid email address).

1
_vaddr() { { cat
    printf %s\\n "$@"
} | grep -o '[^ ]*@[^ ]*' |
    grep -q "$REGEX" && {
        $DO_SUCCESS
        } || $HANDLE_FAILURE
}
mikeserv
  • 58,310
  • grep tries to match every line of $maddr, not $maddr as a whole. Also note that echo does some transformation on its arguments, and should be avoided for arbitrary data. With GNU grep you could do printf %s "$maddr" | grep -zq "$regex" – Stéphane Chazelas Apr 29 '14 at 06:36
  • 1
    @StephaneChazelas - thats a very good point about echo - i should have tried a little harder. In any case - im certainly no stranger to printf. grep -z i do not agree with - that is not a very portable solution. How can you have newlines in email addresses anyway? The biggest advantage to the above is you can accept streamed data and act as necessary without it first needed to be shell parsed. Not in its current form of course, but it takes very little work to get there. – mikeserv Apr 29 '14 at 06:52
  • grep -q on non-text input is not portable either, you need printf '%s\n'. It's about validating input so you can exclude things that are not email addresses (where anything could occur) – Stéphane Chazelas Apr 29 '14 at 06:54
  • @StephaneChezales The "$REGEX" is just a variable and the short-circuit boolean tests either act or dont act according to their assigned function. Inclusion/Exclusion is of course at the implementer's discretion. – mikeserv Apr 29 '14 at 07:00
  • What I meant is if $maddr may contain non-email-addresses (which we want to exclude), it may contain newline characters. Your new version does DO_SUCCESS as long as at least one address matches. – Stéphane Chazelas Apr 29 '14 at 07:09
  • I think i get your point now. It will now handle arbitrary lists of command line args and/or any |pipe stream. I didnt follow you at first because its a foreign concept to me to do arg tests in shell variable form if they havent been narrowed at least to line specificity otherwise. I guess it just didnt occur to me. – mikeserv Apr 29 '14 at 07:22