带引号的Bash参数扩展$ {parameter / pattern / string}

时间:2014-11-18 20:18:57

标签: bash replace quotes

这是我在SO上的第一篇文章(虽然很长一段时间潜伏着),所以我提前为众多的" faux pas"而道歉。我当然要犯的其他错误。

我一直在谷歌上寻找一段时间试图找到一个答案,当内部参数扩展内部双引号时,如何解析引号,似乎我有错误的关键字或非常扭曲的头脑尝试这个。

例如,如果我有一个像It's a complicated string这样的字符串,我想使用bash的参数扩展It'\''s a complicated string将该字符串转换为序列${parameter/pattern/string}我知道我可以使用许多其他内置工具或外部工具之一来实现这一结果(我非常喜欢自己),但这个问题实际上是关于理解bash心中的情况这样我就可以放心了。

Bash's reference似乎没有具体说明在描述其"模式时所遇到的特殊情况"并the closest question on SO似乎不适用于我的情况:

$ echo "$str"
It's a complicated string
$ echo "${str//'/'\''}"
> ^C
$ echo "${str//'/'\''}"
> ^C
$ echo "${str//\'/'\''}"
> ^C
$ echo "${str//\'/\'\''}"
> ^C
$ echo "${str//\'/\'\'\'}"
It\'\'\'s a complicated string
$ echo "${str//\\'/\'\'\'}"
It's a complicated string
$ echo "${str//\\'/\\'\'\'}"
It's a complicated string
$ echo "${str//\\'/\\'\\'\'}"
It's a complicated string
$ echo "${str//\\'/\\'\\'\\'}"
It's a complicated string
$ echo "${str//\\\'/\\'\\'\\'}"
> ^C
$ echo "${str//\\\'/\\\'\\'\\'}"
It's a complicated string
$ echo "${str//\\\'/\\\'\\\'\\'}"
> ^C
$ echo "${str//\\\'/\\\'\\\'\\\'}"
It's a complicated string

> ^C行表示引号未正确解析,我被提示输入更多内容,我每次使用Ctrl-C无情地拒绝。)

你们中的任何一个人都会好好解释一下bash究竟是怎么看到的吗?我真的希望它只是我们之间的沟通问题,我有点喜欢他。 :)

修改

对于那些想知道的人,Etan Reisner的回答是有效的:

$ q=\'
$ echo "${str//\'/$q\'$q}"
It'\''s a complicated string

关于sputnick的回答,我更加困惑:

$ echo "${str//\047/\047\\\047\047}"
It's a complicated string
$ echo "${str//\047/\047\047}"
It's a complicated string
$ echo "${str//\'/\047\'\047}"
It\047\'\047s a complicated string
$ echo "${str//\'/\047\047\047}"
It\047\047\047s a complicated string
$ echo "${str//'/\047\047\047}"
> ^C
$ echo "${str//\047/\047\047\047}"
It's a complicated string
$ echo "${str//\047/\047\\\047\047}"
It's a complicated string

EDIT2:

显然这是一个至少影响bash 4.1和4.2并在bash 4.3中修复的bug。因此,从上述测试中无法理解。

3 个答案:

答案 0 :(得分:2)

以下作品(有或没有双引号):

echo "${str//\'/\'\\\'\'}"

每个单引号都使用反斜杠进行转义,以防止它开始使用单引号字符串。字面反斜杠也在替换模式中被转义。


bash 4.3会话直接复制粘贴:

$ str="It's a complicated string"
$ echo "${str//\'/\'\\\'\'}"
It'\''s a complicated string
$ echo ${str//\'/\'\\\'\'}
It'\''s a complicated string

bash 3.2中的输出完全相同。

答案 1 :(得分:1)

尝试使用单引号的ascii表示,而不是尝试奇怪的转义游戏:\047

man 7 ascii

答案 2 :(得分:1)

我无法解释bash正在做什么,但与@sputnick类似,我的建议是不玩游戏。

q=\'
echo "${str//\'/$q\'$q}"