Quoting special characters
Certain characters may have special meaning to the shell, depending on their context. If you want a command line to include any of the special characters that the shell processes, then you may have to quote these characters to force the shell to treat them as simple characters.
| $ ( " ) & ` ; \ ' Tab Newline Space
* ? [ # ~ = %
In order to quote: | You can: |
---|---|
A single character | Precede the character with a single backslash (\ ) character |
All special characters within a string of characters | Enclose the whole string in single quotes |
All special characters within a string, except for
$ , ` , and \
|
Enclose the whole string in double quotes |
realtime OSin the chapter1.html file:
grep realtime\ OS chapter1.html
grep 'realtime OS' chapter1.html
grep "realtime OS" chapter1.html
grep realtime OS chapter1.html
doesn't do what you might expect, as it attempts to find the
string realtimein the files named OS and chapter1.html.
find -name "*.html" | xargs grep -l '"realtime.*OS"' | less
This command lists all the HTML files
that contain a string consisting of realtime
, followed
by any characters, followed by OS
.
The command line uses
find
to locate all of the files with an extension of html
and passes the list of files to the
xargs
command, which executes the given
grep
command on each file in turn.
All of the output from xargs is then passed to
less,
which displays the output, one screenful at a time.
This command uses quoting in various ways to control when the special characters are processed, and by which process:
- If you don't put quotes around the
*.html
, the shell interprets the*
, and passes to find the list of files in the current directory with an extension ofhtml
. If you quote the*.html
, the shell passes the string as-is to find, which then uses it to match all of the files in this directory and below in the filesystem hierarchy with that extension. - In a similar way, if you don't quote the
realtime.*OS
string at all, the shell generates a list of files that match the pattern. Quoting it once ("realtime.*OS"
) works for a single invocation of grep, but this example has the added complexity of the xargs command. - The xargs command takes a command line as its argument,
and the shell interprets this command line for each item that's passed to
xargs.
If you don't want the
realtime.*OS
string to be interpreted by the shell at all, you need to put nested quotes around the pattern that you want to pass to grep:xargs grep -l '"realtime.*OS"'
- The quoting also indicates when you want to execute the
less command.
As given, the shell passes the output from all of the invocations
of xargs to less.
In contrast, this command:
passes the command:find -name "*.html" | xargs 'grep -l "realtime.*OS" | less'
to xargs, which will have quite different results—if it works at all.grep -l "realtime.*OS" | less
For more information, see
Quoting
in the entry for ksh in the Utilities Reference.