Issue
In C#, there is a verbatim string so that,
string c = "hello \t world"; // hello world
string d = @"hello \t world"; // hello \t world
I am new to shell script, is there a similar method in shell?
Because I have many folders with the name like "Apparel & Accessories > Clothing > Activewear", I want to know if there is a easy way to process the escape characters without write so many .
test.sh
director="Apparel & Accessories > Clothing > Activewear"
# any action to escape spaces, &, > ???
hadoop fs -ls $director
Solution
For definining the specific string in your example, Apparel & Accessories > Clothing > Activewear
, either double quotes or single quotes will work; referring to it later is a different story, however:
In the shell (any POSIX-compatible shell), how you refer to a variable is just as important as how you define it.
To safely refer to a previously defined variable without side-effects, enclose it in double quotes, e.g., "$directory"
.
To define [a variable as] a literal (verbatim) string:
(By contrast, to define a variable with embedded variable references or embedded command substitutions or embedded arithmetic expressions, use double quotes ("
).)
If your string contains NO single quotes:
Use a single-quoted string, e.g.:
directory='Apparel & Accessories > Clothing > Activewear'
A single-quoted string is not subject to any interpretation by the shell, so it's generally the safest option for defining a literal. Note that the string may span multiple lines; e.g.:
multiline='line 1
line 2'
If your string DOES contain single quotes (e.g.,
I'm here.
) and you want a solution that works in all POSIX-compatible shells:- Break the string into multiple (single-quoted) parts and splice in single-quote characters:
Note: Sadly, single-quoted strings cannot contain single quotes, not even with escaping.
directory='I'\''m here.'
The string is broken into into single-quoted I
, followed by literal '
(escaped as an unquoted string as \'
), followed by single-quoted m here.
. By virtue of having NO spaces between the parts, the result is a single string containing a literal single quote after I
.
Alternative: if you don't mind using a multiline statement, you can use a quoted here document, as described at the bottom.
If your string DOES contain single quotes (e.g.,
I'm here.
) and you want a solution that works inbash
,ksh
, andzsh
:Use ANSI-C quoting:
directory=$'I\'m here.'
Note: As you can see, ANSI-C quoting allows for escaping single quotes as \'
, but note the additional implications: other \<char>
sequences are subject to interpretation, too; e.g., \n
is interpreted as a newline character - see http://www.gnu.org/software/bash/manual/bash.html#ANSI_002dC-Quoting
Tip of the hat to @chepner, who points out that the POSIX-compatible way of directly including a single quote in a string to be used verbatim is to use read -r
with a here document using a quoted opening delimiter (the -r
option ensures that \
characters in the string are treated as literals).
# *Any* form of quoting, not just single quotes, on the opening EOF will work.
# Note that $HOME will by design NOT be expanded.
# (If you didn't quote the opening EOF, it would.)
read -r directory <<'EOF'
I'm here at $HOME
EOF
- Note that here documents create stdin input (which
read
reads in this case). Therefore, you cannot use this technique to directly pass the resulting string as an argument.
Answered By - mklement0 Answer Checked By - Gilberto Lyons (WPSolving Admin)