23

What is the difference between grep apple file and grep "apple" file? What does putting the quotation marks do? They both appear to work and do the exact same thing (display same line).

2 Answers 2

45
+500

The quotation marks have an effect on what characters your shell considers special and to have a syntactic meaning. In your example this doesn't make a difference because apple contains no such characters.

But consider another example: grep apple tree file will search for the word apple in the files tree and file, whereas grep "apple tree" file will search the word apple tree in the file file. The quotation marks tell bash, that the word space in "apple tree" does not start a new parameter but shall be part of the current parameter. grep apple\ tree file would produce the same result, because \ tells bash to disregard the special meaning of the following character and treat it literally.

2
  • 2
    This is also visible with wildcards. If you do grep a*b equations.txt then it will search for a*b, unless there is a file in the current directory starting with a, and ending in b, in which case (because (ba)sh will expand the filenames on the command line) grep will be called with complete different parameters, resulting in different results. This is usually more of an issue with find, as a command like find . -name *.txt will result in unexpected behaviour, if there is a txt file in the current directory. It is better to use quotes in this case.
    – SztupY
    Oct 3, 2013 at 12:51
  • 4
    Another important point is the difference between double quotes (") and single quotes ('). Single quotes prevent interpretation of certain characters such as $, whereas double quotes allow interpretation. E.g. grep '${USER}' will look for the text ${USER}, whereas grep "${USER}" will look for the text that the variable USER contains (e.g. johnstacen). Oct 9, 2013 at 15:45
23

Double quotes allow evaluation, single quotes prevent evaluaton, no quotes allow wildcard expansion, when used on command line. As contrived examples:

[user@work test]$ ls .
A.txt B.txt C.txt D.cpp

# The following is the same as writing echo 'A.txt B.txt C.txt D.cpp'
[user@work test]$ echo *
A.txt B.txt C.txt D.cpp

[user@work test]$ echo "*"
*

[user@work test]$ echo '*'
*

# The following is the same as writing echo 'A.txt B.txt C.txt'
[user@work test]$ echo *.txt
A.txt B.txt C.txt

[user@work test]$ echo "*.txt"
*.txt

[user@work test]$ echo '*.txt'
*.txt

[user@work test]$ myname=is Fred; echo $myname
bash: Fred: command not found

[user@work test]$ myname=is\ Fred; echo $myname
is Fred

[user@work test]$ myname="is Fred"; echo $myname
is Fred

[user@work test]$ myname='is Fred'; echo $myname
is Fred

Understanding the way quotes work is pivotal to understanding Bash. For example:

# for will operate on each file name separately (like an array), looping 3 times.
[user@work test]$ for f in $(echo *txt); do echo "$f"; done;
A.txt
B.txt
C.txt

# for will see only the string, 'A.txt B.txt C.txt' and loop just once.
[user@work test]$ for f in "$(echo *txt)"; do echo "$f"; done;
A.txt B.txt C.txt

# this just returns the string - it can't be evaluated in single quotes.
[user@work test]$ for f in '$(echo *txt)'; do echo "$f"; done;
$(echo *txt)

You can use single quotes to pass a command via a variable. Single quotes will prevent evaluation. Double quotes will evaluate.

# This returns three distinct elements, like an array.
[user@work test]$ echo='echo *.txt'; echo $($echo)
A.txt B.txt C.txt

# This returns what looks like three elements, but it is actually a single string.
[user@work test]$ echo='echo *.txt'; echo "$($echo)"
A.txt B.txt C.txt

# This cannot be evaluated, so it returns whatever is between quotes, literally.
[user@work test]$ echo='echo *.txt'; echo '$($echo)'
$($echo)

You can use single quotes inside double quotes and you can use double quotes inside double quotes, but double quotes inside single quotes should not be done (without escaping them) will not be evaluated, they will be interpreted literally. Single quotes within single quotes should not be done (without escaping them).

You'll need to gain a thorough understanding of quotes to use Bash effectively. Very important!

As a general rule, I don't use quotes if I want Bash to expand something into elements (like an array), I use single quotes for literal strings that are not to be altered, and I make liberal use of double quotes for variables that are likely to return any type of string. This is to ensure that spaces and special characters will be preserved.

2
  • How would you use double quotes inside double quotes??? Is that a typo? And why should I escape double quotes inside single quotes instead? I guess you mixed the sentences up maybe?
    – Byte Commander
    Oct 15, 2015 at 15:38
  • @ByteCommander Yes the concept of double quotes placed inside double quotes is used quite commonly - see this post for a prominent working example. It's usually done to protect strings that contain spaces, often with respect to path strings. Double quotes can be used within single quotes with or without escaping, but they will be interpreted literally, that is they will not lead to evaluation. I'll clarify this point in the post.
    – AsymLabs
    Oct 15, 2015 at 18:06

You must log in to answer this question.

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