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
  • 55,929
  • 26
  • 146
  • 227
Wanderer
  • 639
  • 3
  • 7
  • 11

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).

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
1
_vaddr() { { cat
    printf %s\\n "$@"
} | grep -o '[^ ]*@[^ ]*' |
    grep -q "$REGEX" && {
        $DO_SUCCESS
        } || $HANDLE_FAILURE
}
mikeserv
  • 57,448
  • 9
  • 113
  • 229
  • `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](http://unix.stackexchange.com/a/65819/22565). 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