Question: I need to be able to export some variables from a file, so that I can use it in my BASH script. the file content is something like this:

```
my.variable.var1=a-long-ling.with.lot_of_different:characters:and_numbers
my.variable.another.var2=another-long-ling.with.lot_of_different:characters:and_numbers
my.variable.number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers

```

First I tried sourcing it using `source` as they are and got the error message saying: `command not found`. I tried using `export`, which gave me error message saying: `not a valid identifier`.

I think I can only export if I change my variable from `my.variable.var1` to `my_variable_var1`.  

I am able to do this by cutting the line at `=` and then replacing all `.`s with `_`s and then adding the variables back.

So my question is, is it possible to change:

```
my.variable.var1=a-long-ling.with.lot_of_different:characters:and_numbers
my.variable.another.var2=another-long-ling.with.lot_of_different:characters:and_numbers
my.variable.number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers

```

to

```
my_variable_var1=a-long-ling.with.lot_of_different:characters:and_numbers
my_variable_another_var2=another-long-ling.with.lot_of_different:characters:and_numbers
my_variable_number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers

```

using any of those cool 'one liners'? Would love to use that, plus a good learning.

Answer: 
With `sed`:

```
sed -e :1 -e 's/^\([^=]*\)\./\1_/;t1'

```

That is replace a sequence of characters other than `.` at the beginning of the line followed by `.` by that same sequence and `_`, and repeat the process until it no longer matches.

With `awk`:

```
awk -F = -v OFS== '{gsub(/\./, "_", $1); print}'

```

Now, in case the right hand side of the `=` contains characters special to the shell (`\`"$&();'#~<>...`, space, tab, other blanks...), you may want to quote it:

```
sed "s/'/'\\\\''/g;:1"'
     s/^\([^=]*\)\./\1_/;t1'"
     s/=/='/;s/\$/'/"

```

Or:

```
awk -F = -v q="'" -v OFS== '
   {gsub(q, q "\\" q q)
    gsub(/\./, "_", $1)
    $2 = q $2
    print $0 q}'

```
Here's another `sed`:

```
sed 'h;s/\./_/g;G;s/=.*=/=/'

```

This one does only two substitutions, irrespective of the number of dots preceding the `=` so with an input like:

```
my.var.an.other.var.with.many.dots=line.with.many:chars:and_numbers.and.stuff

```

the result is

```
my_var_an_other_var_with_many_dots=line.with.many:chars:and_numbers.and.stuff

```

This works OK when there's one `=` char per line (as in your sample input).  

A more generic approach that always replaces only up to the first `=` (and only if the line contains at least one `=`) even if there are multiple `=` chars per line:

```
sed '/=/{                   # if line matches =
h                           # copy pattern space over the hold space
s/\./_/g                    # replace all . with =
G                           # append hold space content to pattern space
s/=.*\n[^=]*=/=/            # replace from the first = up to the first = after
}'                          # the newline character with a single =

```

or

```
sed -e '/=/{h;s/\./_/g;G;s/=.*\n[^=]*=/=/' -e '}'

```

so with an input like:

```
my.var.with.many.dots.but.no.equal.sign.and.stuff
my.var.with.many.dots=line.with.many:chars:numbers_and.stuff
other.var.with.many.dots=and.with.more.than=one.equal.sign=and.stuff

```

it outputs:

```
my.var.with.many.dots.but.no.equal.sign.and.stuff
my_var_with_many_dots=line.with.many:chars:numbers_and.stuff
other_var_with_many_dots=and.with.more.than=one.equal.sign=and.stuff

```