How can I escape a double quote inside double quotes?

How can I escape double quotes inside a double string in Bash?

For example, in my shell script

#!/bin/bash dbload="load data local infile \"'gfpoint.csv'\" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY \"'\n'\" IGNORE 1 LINES" 

I can't get the ENCLOSED BY '\"' with double quote to escape correctly. I can't use single quotes for my variable, because I want to use variable $dbtable.

8

9 Answers

Use a backslash:

echo "\"" # Prints one " character. 
3

A simple example of escaping quotes in the shell:

$ echo 'abc'\''abc' abc'abc $ echo "abc"\""abc" abc"abc 

It's done by finishing an already-opened one ('), placing the escaped one (\'), and then opening another one (').

Alternatively:

$ echo 'abc'"'"'abc' abc'abc $ echo "abc"'"'"abc" abc"abc 

It's done by finishing already opened one ('), placing a quote in another quote ("'"), and then opening another one (').

More examples: Escaping single-quotes within single-quoted strings

3

Keep in mind that you can avoid escaping by using ASCII codes of the characters you need to echo.

Example:

echo -e "This is \x22\x27\x22\x27\x22text\x22\x27\x22\x27\x22" This is "'"'"text"'"'" 

\x22 is the ASCII code (in hex) for double quotes and \x27 for single quotes. Similarly you can echo any character.

I suppose if we try to echo the above string with backslashes, we will need a messy two rows backslashed echo... :)

For variable assignment this is the equivalent:

a=$'This is \x22text\x22' echo "$a" # Output: This is "text" 

If the variable is already set by another program, you can still apply double/single quotes with sed or similar tools.

Example:

b="Just another text here" echo "$b" Just another text here sed 's/text/"'\0'"/' <<<"$b" #\0 is a special sed operator Just another "0" here #this is not what i wanted to be sed 's/text/\x22\x27\0\x27\x22/' <<<"$b" Just another "'text'" here #now we are talking. You would normally need a dozen of backslashes to achieve the same result in the normal way. 
2

Bash allows you to place strings adjacently, and they'll just end up being glued together.

So this:

echo "Hello"', world!' 

produces

Hello, world! 

The trick is to alternate between single and double-quoted strings as required. Unfortunately, it quickly gets very messy. For example:

echo "I like to use" '"double quotes"' "sometimes" 

produces

I like to use "double quotes" sometimes 

In your example, I would do it something like this:

dbtable=example dbload='load data local infile "'"'gfpoint.csv'"'" into '"table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '"'"'"' LINES "'TERMINATED BY "'"'\n'"'" IGNORE 1 LINES' echo $dbload 

which produces the following output:

load data local infile "'gfpoint.csv'" into table example FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY "'\n'" IGNORE 1 LINES 

It's difficult to see what's going on here, but I can annotate it using Unicode quotes. The following won't work in Bash – it's just for illustration:

dbload=load data local infile "’“'gfpoint.csv'”‘" into ’“table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '”‘"’“' LINES ”‘TERMINATED BY "’“'\n'”‘" IGNORE 1 LINES

The quotes like “ ‘ ’ ” in the above will be interpreted by bash. The quotes like " ' will end up in the resulting variable.

If I give the same treatment to the earlier example, it looks like this:

echo I like to use "double quotes" sometimes

1

Store the double quote character in a variable:

dqt='"' echo "Double quotes ${dqt}X${dqt} inside a double quoted string" 

Output:

Double quotes "X" inside a double quoted string 
2

Check out printf...

#!/bin/bash mystr="say \"hi\"" 

Without using printf

echo -e $mystr 

Output: say "hi"

Using printf

echo -e $(printf '%q' $mystr) 

Output: say \"hi\"

3

Make use of $"string".

In this example, it would be,

dbload=$"load data local infile \"'gfpoint.csv'\" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY \"'\n'\" IGNORE 1 LINES" 

Note (from the man page):

A double-quoted string preceded by a dollar sign ($"string") will cause the string to be translated according to the current locale. If the current locale is C or POSIX, the dollar sign is ignored. If the string is translated and replaced, the replacement is double-quoted.

1

For use with variables that might contain spaces in you Bash script, use triple quotes inside the main quote, e.g.:

[ "$(date -r """$touchfile""" +%Y%m%d)" -eq "$(date +%Y%m%d)" ] 

Add "\" before double quote to escape it, instead of \

#! /bin/csh -f set dbtable = balabala set dbload = "load data local infile "\""'gfpoint.csv'"\"" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '"\""' LINES TERMINATED BY "\""'\n'"\"" IGNORE 1 LINES" echo $dbload # load data local infile "'gfpoint.csv'" into table balabala FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY "''" IGNORE 1 LINES 
1

You Might Also Like