How can I escape a double quote inside double quotes?

BashQuotes

Bash Problem Overview


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.

Bash Solutions


Solution 1 - Bash

Use a backslash:

echo "\""     # Prints one " character.

Solution 2 - Bash

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

Solution 3 - Bash

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.

Solution 4 - Bash

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

Solution 5 - Bash

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

Solution 6 - Bash

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"

Solution 7 - Bash

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.

Solution 8 - Bash

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)" ]

Solution 9 - Bash

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSean NguyenView Question on Stackoverflow
Solution 1 - BashPeterView Answer on Stackoverflow
Solution 2 - BashkenorbView Answer on Stackoverflow
Solution 3 - BashGeorge VasiliouView Answer on Stackoverflow
Solution 4 - BashBeetleView Answer on Stackoverflow
Solution 5 - Bash12oclockerView Answer on Stackoverflow
Solution 6 - BashDanny HongView Answer on Stackoverflow
Solution 7 - BashTrisha ChatterjeeView Answer on Stackoverflow
Solution 8 - BashMajalView Answer on Stackoverflow
Solution 9 - BashShilvView Answer on Stackoverflow