0

I am writing a script and part of it involves replacing few parameters in a file.

I am trying to find and replace the parameter and need to debug sed.

sed -i "s/"$DEFAULT_MAIL_DOMAIN = "padl.com";"/"$DEFAULT_MAIL_DOMAIN = "$E_DOMAIN";"/g" /usr/share/migrationtools/migrate_common.ph

Target file:

# Default DNS domain
$DEFAULT_MAIL_DOMAIN = "padl.com";

# Default base 
$DEFAULT_BASE = "dc=padl,dc=com"

Script:

echo "Enter the email domain"
read E_DOMAIN
echo "The email domain will be "$E_DOMAIN".com"
sleep 2
E_DOMAIN_VAR=$E_DOMAIN.com
sed -i "s/"$DEFAULT_MAIL_DOMAIN = "padl.com";"/"$DEFAULT_MAIL_DOMAIN = "$E_DOMAIN";"/g" /usr/share/migrationtools/migrate_common.ph
2
  • Should the double quotes around "padl.com" be part of the pattern? In that case they need to be escaped: \"padl.com\". The same goes for any other double quotes that sed needs to see.
    – Kusalananda
    Commented May 3, 2017 at 15:41
  • 2
    Instead of showing us the strace which is not at all relevant here, please edit your question and i) show us your input file; ii) show us what part of it you are trying to match; iii) show us how you set your $DEFAULT_MAIL_DOMAIN variable before using it in the sed command; iv) explain what actually happens when you run the sed.
    – terdon
    Commented May 3, 2017 at 16:19

2 Answers 2

4

I would recommend something more like the following:

sed -i 's|$DEFAULT_MAIL_DOMAIN = \"padl.com\";|$DEFAULT_MAIL_DOMAIN = \"$E_DOMAIN\";|' /usr/share/migrationtools/migrate_common.ph

Changes I made:

  • changed to single quotation marks around the sed substitution. All those double quotes you had going on were bound to cause trouble.
  • Changed from / to | for the sed substition syntax. This part is not necessary. I just prefer it. You can keep / if you'd like.
  • Next I removed the double quotation marks around your search and replacement texts. There wasn't a need for them.
  • Escaped the double quotation marks that are actually in the text of the file.
  • removed the global flag at the end of the sed substitution. This looks like a parameter in a configuration file, it's only going to happen once per line (and probably once per file).
5
  • Single quotes will not work using variables like $DEFAULT inside sed code blocks. Commented May 3, 2017 at 16:14
  • 2
    @GeorgeVasiliou as I understand it, he's not actually trying to get bash to interpret any variables. Those are variables that whatever application uses that file interprets. The sed command is searching and replacing that actual text.
    – TopHat
    Commented May 3, 2017 at 16:15
  • TopHat - no, both you and @George are only partially right: OP wants to replace the value of the key $DEFAULT_MAIL_DOMAIN (so here $... should be treated as a literal string) with the value of $E_DOMAIN so the latter has to be expanded (it's the user input no ?) which won't happen with your solution because everything is enclosed in single quotes. As a side note: you don't need to escape double quotes when enclosed in single quotes. Commented May 3, 2017 at 17:22
  • Sadly the question originally didn't have the actual input file. About quoting quotes, in the shell you usually don't want to (not just don't need to) escape double quotes within single quotes: echo 'foo\"bar' will display foo\"bar, with the backslash. Though sed will eat the backslash, so here it's ok.
    – ilkkachu
    Commented May 3, 2017 at 17:40
  • According to the standard, it's undefined what to do with \". The sed flavours I know will ignore the backslash, I think, but there may be implementations using this for some strange extension.
    – Philippos
    Commented May 3, 2017 at 20:50
2

If $DEFAULT_MAIL_DOMAIN and the quotes are a literal part of the file, we need to use single-quotes or backslashes to escape them. So either of the following:

$ E_DOMAIN=foobar.com
$ sed -e 's/$DEFAULT_MAIL_DOMAIN = "padl.com"/$DEFAULT_MAIL_DOMAIN = "'"$E_DOMAIN"'"/' file
# Default DNS domain
$DEFAULT_MAIL_DOMAIN = "foobar.com";
...
$ sed -e "s/\$DEFAULT_MAIL_DOMAIN = \"padl.com\"/\$DEFAULT_MAIL_DOMAIN = \"$E_DOMAIN\"/" file
# Default DNS domain
$DEFAULT_MAIL_DOMAIN = "foobar.com";

In the first, the quotes are interpreted like this:

'.../$DEFAULT_MAIL_DOMAIN = "'"$E_DOMAIN"'"/'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^           ^^^^  - single-quoted, literal ""s
                              ^^^^^^^^^^^  - double-quoted, var expanded

In the second, the whole thing is a double-quoted string, with the problematic $ and " escaped. But not the $ in $E_DOMAIN, since we want to expand that variable.

I'm not sure if the variable should be E_DOMAIN or E_DOMAIN_VAR, you added the .com suffix to the latter, but used the former in the sed command. In any case, /, & or newline in the variable will be processed specially by sed, but a domain name shouldn't contain those.


In your snippet, the quoting is slightly off:

sed -i "s/"$DEFAULT_MAIL_DOMAIN = "padl.com";"/"$DEFAULT_MAIL_DOMAIN = "$E_DOMAIN";"/g" 

The first part "s/" is a quoted string, then $DEFAULT_MAIL_DOMAIN is outside quotes, so is expanded as a variable (probably to an empty string). The spaces are also unquoted, so sed gets multiple arguments, and will likely complain. "padl.com" is again quoted, but the semicolon isn't, so the shell will interpret it as ending the command.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .