0

Suppose i have a variable $email whose value is stack.over@gmail.com.I want to add a \ before every dot except the last dot and store it in a new variable $email_soa.

$email_soa should be stack\.over@gmail.com in this case.

user2650277
  • 6,289
  • 17
  • 63
  • 132

4 Answers4

4
sed -E 's/\./\\\./g;s/(.*)\\\./\1\./'

should do it.

Test

$ var="stack.over@flow.com"
$ echo $var | sed -E 's/\./\\\./g;s/(.*)\\\./\1./'
stack\.over@flow.com
$ var="stack.over@flow.com."
$ echo $var | sed -E 's/\./\\\./g;s/(.*)\\\./\1./'
stack\.over@flow\.com.

Note

The \\ makes a literal backslash and \. makes a literal dot

sjsam
  • 21,411
  • 5
  • 55
  • 102
  • 2
    The `.` in the replacement part doesn't need to be escaped. – Tom Fenech Jul 26 '16 at 16:59
  • 1
    Always nice to see a well phrased sed command. If you are really worried about portability, though, the `-E` for extended regular expressions is not supported in POSIX 7 (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html). I am sure you will have no problems in the real world, though. – Dr K Jul 26 '16 at 18:14
  • @DrK : If I'm really worried about portability then I would replace the `-E` and escape the parenthesis. Also have a look at [\[ this \]](http://stackoverflow.com/a/3139925/1620779) . `-E` would work fine on most of the unices including Macs. – sjsam Jul 26 '16 at 18:36
2

You can use gawk:

var="stack.over@gmail.com"
gawk -F'.' '{OFS="\\.";a=$NF;NF--;print $0"."a}' <<< "$var"

Output:

stack\.over@gmail.com

Explanation:

  • -F'.' splits the string by dots
  • OFS="\\." sets the output field separator to \.
  • a=$NF saves the portion after the last dot in a variable 'a'. NF is the number of fields.
  • NF-- decrements the field count which would effectively remove the last field. This also tells awk to reassemble the record using the OFS This feature does at least work with GNU's gawk.
  • print $0"."a prints the reassmbled record along with a dot and the value of a
hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • As far as I remember, decrementing `NF` isn't guaranteed to remove the last field in all versions of awk. – Tom Fenech Jul 26 '16 at 17:01
  • @TomFenech I've tried `busybox awk` which I have by the hand atm. It supports it as well. – hek2mgl Jul 26 '16 at 17:05
  • @TomFenech POSIX doesn't say anything about assigning to `NF`, meaning you are right, it is not guaranteed to work. – hek2mgl Jul 26 '16 at 17:18
2

You could use perl to do this:

perl -pe 's/\.(?=.*\.)/\\./g' <<<'stack.over@gmail.com'

Add a slash before any dots that have a dot somewhere after them in the string.

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
1

How about this:

temp=${email%.*}
email_soa=${temp/./\\.}.${email##*.}
Dr K
  • 416
  • 2
  • 5
  • Nice. but this is not a portable solution imho. – sjsam Jul 26 '16 at 17:15
  • 2
    I am curious, why do you not think this is portable? The question was tagged with `bash` so do you mean across different versions of bash? – Dr K Jul 26 '16 at 17:22
  • 1
    yes, kindly have a look at the [\[ changelog \]](http://wiki.bash-hackers.org/scripting/bashchanges) – sjsam Jul 26 '16 at 17:27
  • Fair enough. I guess it does have to be bash 3.2 or higher. So anyone a bit more than a decade behind on their updates might run into problems. – Dr K Jul 26 '16 at 17:52