如何在 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
。
$dbtable
的值,则存在风险。不过,这非常并不常见,因为最终用户通常不会通过 SSH 连接到机器来加载他们的数据。
使用反斜杠:
echo "\"" # Prints one " character.
在 shell 中转义引号的一个简单示例:
$ echo 'abc'\''abc'
abc'abc
$ echo "abc"\""abc"
abc"abc
这是通过完成一个已经打开的 ('
),放置转义的 (\'
),然后打开另一个 ('
) 来完成的。
或者:
$ echo 'abc'"'"'abc'
abc'abc
$ echo "abc"'"'"abc"
abc"abc
它是通过完成已打开的一个 ('
)、在另一个引号 ("'"
) 中放置一个引号,然后打开另一个 ('
) 来完成的。
更多示例:Escaping single-quotes within single-quoted strings
echo "abc\"abc"
足以产生 abc"abc
就像彼得回答中的那样。
请记住,您可以通过使用需要回显的字符的 ASCII 代码来避免转义。
例子:
echo -e "This is \x22\x27\x22\x27\x22text\x22\x27\x22\x27\x22"
This is "'"'"text"'"'"
\x22
是双引号的 ASCII 代码(十六进制),而 \x27
是单引号的 ASCII 代码。同样,您可以回显任何字符。
我想如果我们尝试用反斜杠回显上面的字符串,我们将需要一个凌乱的两行反斜杠回显...... :)
对于变量赋值,这是等价的:
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.
echo 'export PS1='\[\033[00;31m\]${?##0}$([ $? -ne 0 ] && echo \x22 \x22)\[\033[00;32m\]\u\[\033[00m\]@\[\033[00;36m\]\h\[\033[00m\][\[\033[01;33m\]\d \t\[\033[00m\]] \[\033[01;34m\]\w\n\[\033[00m\]$( [ ${EUID} -ne 0 ] && echo \x22$\x22 || echo \x22#\x22 ) '' >> ~/.profile
的问题
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
”
echo
示例的一个微妙之处在于,在这里我实际上给 echo 三个单独的参数,因为字符串没有接触。但是 echo
命令打印所有三个,用空格分隔,所以它有点像你期望的那样。不同之处在于,如果您输入 echo a b c
,它将输出 a b c
,而如果您输入 echo 'a b c'
,它将输出 a b c
。
将双引号字符存储在变量中:
dqt='"'
echo "Double quotes ${dqt}X${dqt} inside a double quoted string"
输出:
Double quotes "X" inside a double quoted string
看看打印...
#!/bin/bash
mystr="say \"hi\""
不使用 printf
echo -e $mystr
输出:说“嗨”
使用 printf
echo -e $(printf '%q' $mystr)
输出:说“嗨”
printf
也会转义更多字符,例如 '
、(
和 )
printf %q
生成为 eval
准备的字符串,而不是为 echo -e
格式化的字符串。
echo
包装 printf
。您的两个示例都引用了错误。正确的解决方法是对变量进行双引号。
使用 $"string"。
在这个例子中,它将是,
dbload=$"load data local infile \"'gfpoint.csv'\" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY \"'\n'\" IGNORE 1 LINES"
注意(来自 man page):
以美元符号 ($"string") 开头的双引号字符串将导致根据当前语言环境翻译该字符串。如果当前语言环境是 C 或 POSIX,则忽略美元符号。如果字符串被翻译和替换,则替换是双引号。
要与 Bash 脚本中可能包含空格的变量一起使用,请在主引号内使用三引号,例如:
[ "$(date -r """$touchfile""" +%Y%m%d)" -eq "$(date +%Y%m%d)" ]
在双引号之前添加 "\"
以将其转义,而不是 \
#! /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
问题的 csh
答案?两者完全不同,互不相容。
不定期副业成功案例分享
x=ls; if [ -f "$(which "\""$x"\"")" ]; then echo exists; else echo broken; fi;
损坏,而... [ -f "$(which $x)" ]; ...
或... [ -f $(which "$x") ]; ...
工作正常。当$x
或$(which "$x")
的结果给出任何带有空格或其他特殊字符的内容时,就会出现问题。一种解决方法是使用变量来保存which
的结果,但是 bash 真的无法转义引号还是我做错了什么?grep -oh "\"\""$counter"\""\w*"
作为 bash 语法的一部分,其中$counter
是一个变量。它不喜欢任何想法