When to use single quotes, double quotes, or no quotes in grep?

42,625

Solution 1

This is actually dependent on your shell. Quotes (either kind) are primarily meant to deal with whitespace. For instance, the following:

grep hello world file1

will look for the word "hello" in files called "world" and "file1", while

grep "hello world" file1

will look for "hello world" in file1.

The choice between single or double quotes is only important if the search string contains variables or other items that you expect to be evaluated. With single quotes, the string is taken literally and no expansion takes place. With double quotes, variables are expanded. For example (with a Bourne-derived shell such as Bash or ZSH):

VAR="serverfault"
grep '$VAR' file1
grep "$VAR" file1

The first grep will look for the literal string "$VAR1" in file1. The second will expand the "$VAR" variable and look for the string "serverfault" in file1.

Solution 2

James is correct, but to add some more data, I think that the best way to think about it is as arguments to the command: do you intend "hello" and "world" to be two arguments or "hello world" to be one argument.

Also, doublequotes allow interpretation of more than just variables. Exactly what depends on your shell, but check into history expansion, brace expansion, and filename expansion.

It's also important to note that there are some instances where you need to use both types of quotes in a single argument. Remember that (by default) arguments are delimited by whitespace, so if you don't leave any space, you're still specifying the same argument.

Most shells' singlequote mechanism doesn't allow for any special characters, which means that any instance of another singlequote, even if it appears to be escaped, ends the quote. It is therefore impossible to pass a string with a singlequote inside a singlequoted string, and you have to use doublequotes. This can be a pain when you want to pass an argument that contains singlequotes and something that would be interpreted, but you don't want to be. For example, if you wanted to pass the literal string '$VAR' is a variable, you have to do it this way:

"'"'$VAR'"' is a variable"

That's actually a concatenation of three quote-escaped strings:

"'"
'$VAR'
"' is a variable"

Or, with the quotes removed:

'
$VAR
' is a variable

Actually, with most shells, you could also do it this way:

"'\$VAR' is a variable"

... where the backslash ("\") tells the shell to accept the following character literally and not do any expansion on it.

But there are some instances where you end up having to do it the multi-string-concatenation way, not that I can actually come up with an example right now.

Share:
42,625

Related videos on Youtube

Jesse Nickles
Author by

Jesse Nickles

I'm passionate about free speech, FOSS, and the open web, and my company LittleBizzy maintains several free WordPress plugins being used by organizations like United Nations, Emirates Airlines, and Flipkart. I also maintain SlickStack on GitHub, an open-source Bash script for deploying LEMP stack servers on Ubuntu with an emphasis on technical SEO. If you want market-leading performance and security for your WordPress websites without the headache of Docker containers (or having to pay for overpriced "premium" web hosting services), consider checking it out and getting involved. Contact me: https://jessenickles.com/contact

Updated on September 17, 2022

Comments

  • Jesse Nickles
    Jesse Nickles almost 2 years

    While trying to search for a simple pattern "hello" in a file, all the following forms of grep work:

    • grep hello file1
    • grep 'hello' file1
    • grep "hello" file1

    Is there a specific case where one of the above forms work but others do not. Does it make any difference if I use one in place of another?

  • Steve Townsend
    Steve Townsend almost 13 years
    The key thing to note is that in the original question, grep is actually receiving the exact same arguments every time.
  • Steven Pritchard
    Steven Pritchard almost 13 years
    Be careful there. $ is end-of-line in a regular expression, so $VAR1 should never actually match anything. It happens to work on GNU grep, but I still wouldn't count on that behavior. You'd need \$VAR1 to safely match the literal string. (And you'd need extra backslashes if that's in double quotes.)
  • CoR
    CoR over 3 years
    @Steven Pritchard: No, you are wrong. "" vs '' is shell issue. "\$VAR" will escape $ in parameter expansion so variable will NOT be substituted with its value. Order of execution is very important here. First shell does all expansions then grep receives expanded string of parameters.
  • Steven Pritchard
    Steven Pritchard over 3 years
    @CoR We're talking about two different things. Ignoring the shell interpolation, $ is the end-of-line anchor in regular expressions. End-of-line + trailing characters is nonsensical, so it appears that GNU grep assumes you mean \$ in that case. I'm just saying I wouldn't count on that behavior.
  • CoR
    CoR over 3 years
    @Steven Pritchard, We can not ignore shell interpretation. In this case we want to do parameter expansion! The whole point is to do param expansion :)