Bash 如何在双引号中转义双引号?

Bash 如何在双引号中转义双引号?,bash,quotes,Bash,Quotes,如何在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" 我无法使用双引号将“\”括起来的正确转义。我无法对变量使用单引号,因为我要使用变量$dbt

如何在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"
我无法使用双引号将“\”括起来的
正确转义。我无法对变量使用单引号,因为我要使用变量
$dbtable

使用反斜杠:

echo "\""     # Prints one " character.

查看printf

#!/bin/bash
mystr="say \"hi\""
不使用printf

echo -e $mystr
输出:说“嗨”

使用printf

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

输出:说“嗨”

一个在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!'
产生

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

$echo“我有时喜欢使用”双引号“
产生

我有时喜欢用“双引号”

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

$dbtable=示例
$dbload='load data local infile'''''gfpoint.csv'''加载到''table$dbtable字段终止于'''s',封闭于''s','行''s'中''
$echo$dbload
将生成以下输出:

将数据本地填充“'gfpoint.csv'”加载到以“'”结尾的表格示例字段中,以“'\n'”结尾的行忽略1行

很难看出这里发生了什么,但我可以使用Unicode引号对其进行注释。以下内容在bash中不起作用–仅用于说明:

dbload=
加载数据本地填充”
'gfpoint.csv”
”到
中“
表$dbtable字段以“,”结尾,“
”行
以“
”结尾“
”\n”
”忽略1行

上面类似“''”的引号将由bash解释。像
“'
这样的引号将在结果变量中结束

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

$echo
我喜欢使用
“双引号”
有时使用

字符串”

在这个例子中

dbload=$“将数据本地填充\”“gfpoint.csv”“\”加载到以“,”结尾的表$dbtable字段中,“,”由“\”括起“,”行以“\”\n“\”结尾的忽略1行”

注(摘自下表):

以美元符号($“字符串”)开头的双引号字符串将导致根据当前区域设置转换字符串。如果当前区域设置为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

我不知道为什么今天在Bash标记的列表中会出现这个老问题,但为了以防万一,请记住,使用需要回送的字符的ASCII码可以避免转义

例如:

echo-e“这是\x22\x27\x22\x27\x22text\x22\x27\x22\x27\x22”
这是“文本”
\x22
是双引号的ASCII码(十六进制),单引号的ASCII码是
\x27
。类似地,您可以回显任何字符

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

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

$a=$'这是\x22text\x22'
$echo“$a”
这是“文本”
如果变量已经由另一个程序设置,您仍然可以使用sed或类似工具应用双引号/单引号

例如:

$b=“这里只是另一个文本”
$echo“$b”
这里还有一段文字

$sed's/text/“'\0'/”将双引号字符存储在变量中:

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

双引号字符串中的双引号“X”

请注意,
printf
也会转义更多的字符,例如
printf%q
eval
生成准备好的字符串,而不是为
echo-e
格式化的字符串。没有理由用字符串包装
printf
。你的两个例子都打破了引用。正确的修复方法是双引号引用变量。另请参阅可能重复的@kenorb看起来不像该问题的重复项…另请参阅@Daenyth这不是您希望最终用户能够访问的命令类型。批量加载脚本通常由受信任的用户(如系统管理员或开发人员)在服务器上运行。是的,如果最终用户控制
$dbtable
的值,则存在风险。不过,这是非常罕见的,因为最终用户通常不会通过SSH将数据加载到机器中,无法正常工作<代码>x=ls;如果[-f“$(哪个“\”“$x”\”)”];然后回声就存在了;否则回声就会破裂;fi给出了断开的代码,而
。。。[-f“$(哪个$x)”]
。。。[-f$(其中“$x”)]工作正常。当
$x
$(其中“$x”)
的结果给出任何带有空格或其他特殊字符的内容时,就会出现问题。一种解决方法是使用一个变量来保存
的结果,而
的结果是
的结果,但是bash真的不能转义引号吗?或者我做错了什么吗?我正在尝试使用以下
grep-oh“\”\“\”“$counter”\”“\w*”
作为bash语法的一部分,在
$counter>中<