0

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  
apaderno
  • 825
Jim
  • 10,120

1 Answers1

3

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).

Kusalananda
  • 333,661
  • 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 https://unix.stackexchange.com/questions/68694/when-is-double-quoting-necessary – 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
  • @Jim The variable is quoted if it appears within a quoted string. I don't know how I can make that more clear. Obviously, a string like "_$var!!!" will contain other stuff than just the value of $var, but it is still a quoted string, and the variable expansion is quoted. – Kusalananda Oct 20 '17 at 20:31
  • So if it contains white spaces it still treated as a single entity? – Jim Oct 20 '17 at 20:34
  • @Jim The quoted string will be a single entity, yes. – Kusalananda Oct 20 '17 at 20:46
  • Does this also include cases that we pass a shell variable to perl? E.g. perl -i.bak -ne "print unless /$MY_VAR/;" /foo/bar/file.txt. Is that also treated as a single entity? – Jim Oct 21 '17 at 18:56
  • @Jim Yes, that is correct. – Kusalananda Oct 21 '17 at 19:03