如何在双引号内转义双引号?

我如何逃脱双引号内的双字符串在Bash?

例如,在我的shell脚本中

#!/bin/bash


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

我无法让带有双引号的ENCLOSED BY '\"'正确转义。我的变量不能使用单引号,因为我想使用变量$dbtable

522402 次浏览

使用反斜杠:

echo "\""     # Prints one " character.

查看printf

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

不使用printf

echo -e $mystr

输出:说“hi”

使用printf

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

输出:say“hi”

一个在shell中转义引号的简单例子:

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

它是通过完成一个已经打开的('),放置转义的(\'),然后打开另一个(')来完成的。

另外:

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

它是通过结束已经打开的一个('),在另一个引号("'")中放置一个引号,然后打开另一个(')来完成的。

更多例子:在单引号字符串中转义单引号

Bash允许您相邻地放置字符串,它们最终会被粘在一起。

所以这个:

echo "Hello"', world!'

生产

Hello, world!

诀窍是根据需要在单引号和双引号字符串之间交替使用。不幸的是,它很快就变得非常混乱。例如:

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

生产

I like to use "double quotes" sometimes

在你的例子中,我会这样做:

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

它产生以下输出:

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

很难看出这里发生了什么,但我可以使用Unicode引号对其进行注释。下面的代码在Bash中不起作用——只是为了说明:

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

bash将对上面的“' '”这样的引号进行解释。像" '这样的引号将在结果变量中结束。

如果我对前面的例子进行同样的处理,它看起来是这样的:

echo I like to use "double quotes" sometimes

使用$"string"。

在这个例子中,它是,

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

注意(来自手册页):

在美元符号($"string")前加双引号的字符串将导致该字符串根据当前语言环境进行翻译。如果当前区域设置为C或POSIX,则忽略美元符号。如果转换并替换了字符串,则替换的字符串会被双引号括起来。

在双引号前添加"\"来转义,而不是\

#! /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

请记住,可以通过使用需要回显的字符的ASCII码来避免转义。

例子:

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

\x22是用于双引号的ASCII码(十六进制),\x27用于单引号。同样,您可以回显任何字符。

我想如果我们尝试用反斜杠回显上面的字符串,我们将需要一个混乱的两行反斜杠回显…:)

对于变量赋值,这是等价的:

a=$'This is \x22text\x22'
echo "$a"


# Output:
This is "text"

如果变量已经由另一个程序设置,您仍然可以使用sed或类似工具应用双引号/单引号。

例子:

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.

将双引号字符存储在变量中:

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

输出:

Double quotes "X" inside a double quoted string

对于Bash脚本中可能包含空格的变量,请在主引号内使用三重引号,例如:

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