Question

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
Was it helpful?

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 in bash, ksh, and zsh:

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

OTHER TIPS

use strong quotes i.e. 'string', allowing escape char or special char for string.

e.g. declare director='Apparel & Accessories > Clothing > Activewear'

also using declare is a good practice while declaring variable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top