I am confused on when we double quote shell variables.
Specifically I am using the following sed replace command:

sed -i.tmp "/$MY_VAR/d" /foo/bar/file.txt  

But I am not quoting $MY_VAR. Is this correct? How can I quote it if not?
The following obviously does not work

sed -i.tmp '/"$MY_VAR"/d' /foo/bar/file.txt  
  • 2
    “Is it correct?” That depends on what you’re trying to do... Do you want to delete lines containing the “$MY_VAR” string (literally), or lines containing the value of the MY_VAR shell variable? – Stephen Kitt Oct 20 '17 at 14:33
  • show the $MY_VAR contents – RomanPerekhrest Oct 20 '17 at 14:33
  • @StephenKitt: The value of course – Jim Oct 20 '17 at 14:34
  • 1
    use double quotes when you want the shell to replace a variable with a value, and use single quotes when you want the literal variable name. – Tim Kennedy Oct 20 '17 at 14:46
  • @RomanPerekhrest: It is a string containing whitespaces no other special chars – Jim Oct 20 '17 at 16:30

In your first command, you are quoting the variable.

The string passed as the second command line argument to sed has double quotes around it, and the variable is within those quotes and will be expanded by the shell.

The second command will not work (as expected), as you point out, because the shell would not expand the value of the variable since it's quoted using single quotes.

The first command is correct, but you will have issues if $MY_VAR contains slashes. If it does, pick a delimiter for the sed pattern that does not occur in $MY_VAR:

sed "\@$MY_VAR@d"

A variable is quoted when it appears in quotes. The variable does not need to be "tightly quoted" to be quoted. That is, within the string "hello $world!", the variable $world is quoted even though it does not appear as "$world".

What matters is that the string as a whole is quoted. If double quotes are used, then the shell will expand any variables within it.

In the example above, the string "\@$MY_VAR@d" is quoted, and the variable $MY_VAR is within it, so it is quoted as well (since it's within the quoted string).

  • My understanding is that the best practice is to always quote shell variables i.e. always use "$MY_VAR" than $MY_VAR. So I was trying to understand if it is applicable to this case. You also in your solution snippet do not quote the variable itself. – Jim Oct 20 '17 at 16:34
  • @Jim The variable will be expanded within double quotes. It is quoted. The double quotes do not have to be "tightly around the variable". What counts is that sed (in this example) gets a single string. – Kusalananda Oct 20 '17 at 17:01
  • They don't have to be tightly around the variable? Then I have completely misunderstood the recommendation. An example post unix.stackexchange.com/questions/68694/… – Jim Oct 20 '17 at 20:23
  • And why did @ need to be escaped in "\@$MY_VAR@d"? – Jim Oct 20 '17 at 20:24
  • 1
    @Jim Any character (other than backslash and newline) can be the delimiter for the regular expression that acts like the address for the command (the command is d in this case), but if the character is not a slash, then it needs to be preceded by a backslash. This is described in the sed manual. – Kusalananda Oct 20 '17 at 20:28

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.