如何在 Bourne Shell 中回显包含 $ 的转义字符串?
user@server:~$ cat test.sh
#!/bin/sh
echo $1
user@server:~$ ./test.sh \$sad\$test
$sad$test
Run Code Online (Sandbox Code Playgroud)
我希望它返回这样的转义版本:
user@server:~$ ./test.sh \$sad\$test
\$sad\$test
Run Code Online (Sandbox Code Playgroud)
我试过用 sed 和 awk 做一些技巧,但没有运气。任何指导将不胜感激。
我假设您希望字符串显示为“shell 引用”。
ksh、bash和zsh 中的printf内置命令都理解格式说明符。实际输出未标准化,可能会因输入字符串而异(见下文)。由于输出形式的变化,您可能无法将一个 shell 的输出与另一个 shell 一起使用(特别是如果您的目标 shell 是功能不太丰富的 shell,如ash、dash等)。%q
zsh还支持在参数扩展中直接生成引号:
echo "${(q)1}" # backslashes, with $'' for unprintable/invalid characters
echo "${(qq)1}" # single quotes
echo "${(qqq)1}" # double quotes
echo "${(qqqq)1}" # $'' quoting
Run Code Online (Sandbox Code Playgroud)
如果你想“推出你自己的”,最简单和最可靠的做法是生成你自己的单引号。一个简单的算法如下:
'\''。这适用于类似 Bourne 的 shell,因为单引号完全是文字1。要表示单引号,请结束当前的单引号范围,提供反斜杠转义的单引号并恢复对字符串其余部分的单引号。上述算法在处理连续单引号和字符串开头和结尾的单引号时效率低下,但它非常可靠且实现起来非常简单。
1其他语言中的单引号通常不完全是字面意思(至少,它们通常允许一些有限的反斜杠转义)。这就是为什么了解将要生成的引用形式的所有引用规则(即引用文本将在何种语言/上下文中使用)至关重要的原因。
以下是printf %q我在本地安装的 shell中的一些示例:
for s in /bin/ksh {,/opt/local}/bin/bash {,/opt/local}/bin/zsh
do
"$s" --version | head -1
"$s" -c 'printf "%q\n" "$@"' - \$sad\$test \'mixed\ quotes\" back\`tick
echo
done
Run Code Online (Sandbox Code Playgroud)
输出:
version sh (AT&T Research) 1993-12-28 s+
'$sad$test'
$'\'mixed quotes"'
'back`tick'
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin10.0)
\$sad\$test
\'mixed\ quotes\"
back\`tick
GNU bash, version 4.2.10(2)-release (i386-apple-darwin10.7.0)
\$sad\$test
\'mixed\ quotes\"
back\`tick
zsh 4.3.9 (i386-apple-darwin10.0)
\$sad\$test
\'mixed\ quotes\"
back\`tick
zsh 4.3.12 (i386-apple-darwin10.7.0)
\$sad\$test
\'mixed\ quotes\"
back\`tick
Run Code Online (Sandbox Code Playgroud)
我们看到ksh似乎“喜欢”用单引号引用,并$''在某些情况下使用这种形式。其他 shell 似乎主要使用反斜杠转义(尽管$''如果存在某些字符,它们也会使用)。
在脚本中:
echo "${1//$/\\$}"
Run Code Online (Sandbox Code Playgroud)
这是 shell 中构建的简单字符串替换。该语法${[VARIABLE_NAME]//[PATTERN]/[REPLACEMENT]}用于全局文字字符串替换。
不知道你为什么要这样做。该脚本实际上只是报告您发送给它的字符串;\$sad\$test计算结果与 完全相同的字符串'$sad$test',除了后者使用单引号来转义$。