Say I have a PHP file with the following code line:

$to = "example-1_2@example-1_2.com";

I want to change only the email address between the two double quote marks to say example@example.com).

I have tried this which failed:

read new_email_address
sed -i 's/^[a-zA-Z0-9-_]*$@^[a-zA-Z0-9-_]*$.^[a-z]*$/"${new_email_address}"/g' FILE
  • You don't say in which way it fails. Error message, no output, unexpected output... In any case, your regular expression matches a line that starts with a hex digit or dash or underscore, which doesn't match the PHP line, and the dollar in the replacement string would be used verbatim, as it is enclosed in single quotes. Thus, it doesn't work at several levels. Mar 14, 2021 at 6:06
  • It's not quite certain what you want to achieve. You want to replace all email addresses in the code, or just example-1_2@example-1_2.com? Or something else? Mar 14, 2021 at 6:06
  • @berndbausch by "hex digit" you mean to a letter or a number, right? About the replacement, I want to replace only the email address example-1_2@example-1_2.com in each occurrence (normally it would occur just once but I it might occur twice or more by some rare copying mistake).
    – timesharer
    Mar 14, 2021 at 6:19
  • Sorry for the "hex digit"; this is incorrect, and yes, letter-or-number would have been correct. I don't know what prevents you from simply replacing the email address itself? For example, sed "s/example-1_2@example-1_2.com/${new_email_address}/"? Mar 14, 2021 at 8:16
  • @berndbausch I am creating an installation script to install a Content-Management-System-Updater (CMSU) which has to include an email and everything is so far automatic besides email setting; which I also want automatic.
    – timesharer
    Mar 14, 2021 at 8:19

2 Answers 2


Just a brief comment about the updated sed command in your question, which currently reads

sed -i 's/^[a-zA-Z0-9-_]*$@^[a-zA-Z0-9-_]*$.^[a-z]*$/"${new_email_address}"/g' FILE

Notice that this contains two invalid character ranges (both read 0-9-_) and that the variable new_email_address would not be expanded by the shell as it is in a single-quoted string. I'm also not sure about what the intention is with $@^ and $.^, as the $ and ^ would be matching those characters literally at those positions in the expression.

Not seeing how the $to variable is used in the rest of the file, I'm going to assume that it's only assigned to in one single place, and that the line that you show occurs exactly like it does in the file.

sed 's/$to = ".*";$/$to = "'"$new_email_address"'";/' file >file.new

There is no point in trying to match an email address since we know already that the $to variable holds an email address. The only thing we need to worry about is trying to find the correct line. Matching email addresses with regular expressions is notoriously difficult.

A few things to note here:

  • The $ in $to does not need special handling as it's not occurring last in the expression. If you use -E to enable extended regular expressions, then firstly, don't, and secondly, escape the $ in $to as \$ in the pattern.
  • The string $to will not be seen as a shell variable as it's within single quotes.
  • $new_email_address is a shell variable, so we're temporarily breaking out of the single quotes to introduce the value of that variable, double quoted.

I would suggest not using -i here, as you don't yet know whether the substitution does the right thing or whether it messes up the file. It's better to write the result to a fresh filename instead.

Also, with -ir, you are instructing sed to use r as the backup file suffix. I assume that you wanted to use the option -r (or -E, which would be more commonly supported). However, neither -r nor -E is needed as we're not using any extended regular expressions for this simple substitution.

Testing the above command:

$ cat file
$to = "example-1_2@example-1_2.com";
$ new_email_address=myself@my.host.here.net
$ sed 's/$to = ".*";$/$to = "'"$new_email_address"'";/' file >file.new
$ cat file.new
$to = "myself@my.host.here.net";
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Kusalananda
    Mar 17, 2021 at 10:38

If you want to replace a string that is (1) between two double-quotes and (2) has a single @ in the middle, this regular expression would match it:


Note that the dash has to be at the end in each character class, and I added a dot before and after the @.

Theoretically, other characters are possible, such as %. With a little research, you may find regular expressions that match email addresses better than that, but let's assume your email addresses conform to this expression.

The problem is the replacement string in your sed program. You need to put it between double-quotes, since it contains a shell variable, and the regular expression also contains double-quotes.

The easiest way of handling this, in my opinion, is by putting backslashes before the double quotes. For example

sed "s/\"[a-zA-Z0-9_.-]*@[a-zA-Z0-9_.-]*\"/\"${new_email}\"/"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.