Bas*_*ian 5 bash escape-characters
我有一个变量,例如a'b,包含一个单引号,在将其写入文件之前,我需要将其替换为两个单引号:a''b.
以下 bash 代码用于为我完成工作......
line="a'b"
echo "${line//\'/\'\'}" > out.txt
Run Code Online (Sandbox Code Playgroud)
...直到今天,我发现根据所使用的 bash 版本有不同的输出:
a''ba\'\'b我试图以多种方式修改上面的行,但无法让它a''b在两个 bash shell 中产生相同的输出。
我最终使用了echo和的组合sed,
echo "$(echo $line | sed "s/'/''/g")" > out.txt
Run Code Online (Sandbox Code Playgroud)
但我仍然想知道是否可以使用更简洁的纯 bash 表达式来完成这项工作。它可以?
其中一个变化的bash-4.3-α,和以前的版本时,bash-4.2版本之间:
当使用模式替换词扩展时,bash 现在通过引号删除来运行替换字符串,因为它允许该字符串中的引号充当转义字符。这不是向后兼容的,因此可以通过将 bash 兼容模式设置为 4.2 来禁用它。
输入:
BASH_COMPAT=4.2
line="a'b"
echo "${line//\'/''}"
Run Code Online (Sandbox Code Playgroud)
输出:
a''b
Run Code Online (Sandbox Code Playgroud)
对于无论版本如何都可以工作的方法(以及它来自的 ksh93 和 mksh 和 zsh 之类的 shell 实现,它们也支持它),您可以将模式和替换存储在变量中:
pattern="'"
replacement="''"
printf '%s\n' "${line//$pattern/$replacement}"
Run Code Online (Sandbox Code Playgroud)
或者
q="'"
printf '%s\n' "${line//$q/$q$q}"
Run Code Online (Sandbox Code Playgroud)
(请注意,在 中zsh,the$pattern被视为固定字符串。如果您希望将其作为通配符模式(此处不适用,因为$pattern不包含通配符),则需要替换$pattern为$~pattern。在其他 shell 中,如果你想$pattern 被当作一个固定的字符串,你需要把它加引号(${line//"$pattern"/$replacement})。