printf '%s' 'abc' | sed 's/./\\&/g' #1, \a\b\c
printf '%s' "`printf '%s' 'abc' | sed 's/./\\&/g'`" #2, &&&
第二个反引号内的表达式返回\a\b\c
,我们有printf '%s' "\a\b\c"
,因此它应该打印\a\b\c
。
我的问题是:为什么第二个脚本会打印&&&
?
请注意:
我可以通过在每个反斜杠前加上另一个反斜杠来使第二个脚本工作(打印\a\b\c
),但我不知道为什么需要它。
一个相关问题: why does this single quoted string get interpreted when it's inside of a command substitution
答案 0 :(得分:2)
这是一个很好的例子,用于显示反向标记和$(cmd)
命令替换之间的区别。
当使用旧式反引号替换形式时,反斜杠 保留其字面含义,除非后跟" $","`"或" \"。 第一个没有反斜杠的反引号会终止命令 代换。使用" $(COMMAND)"形式,所有字符之间 括号组成命令;没有人受到特别对待。
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html
所以看看你的例子,我使用echo
而不是printf
:
kent$ echo 'abc' | sed 's/./\\&/g'
\a\b\c
kent$ echo -E "`echo 'abc' | sed 's/./\\&/g'`"
&&&
kent$ echo -E "$(echo 'abc' | sed 's/./\\&/g')"
\a\b\c
你可以看到,后面的勾选命令替换使你的\\
成为单\
,因此跟随&
一起成为\&
(文字{{1} }})
请注意,我使用&
来禁用反斜杠转义的解释,以便打印出echo -E
。
答案 1 :(得分:1)
因为在第二行:
你说的是:printf '%s' 'abc' -> 'abc'
然后替换:
'abc'| sed 's/./\\&g' -> &&&
The s mean substitute
. mean one character
\\& by a char &
g mean multiple occurrence on the line
所以你说:
将每个字母替换为abc&多次在同一条线上
\\\&
的解释:
Two backslashes become a single backslash in the shell which then in sed escapes the forward slash which is the middle delimiter.
\\& -> \& (which makes the forward & a regular character instead of a delimiter)
Three of them: The first two become one in the shell which then escape the third one in sed
\\\& -> \\&
最后!不要忘记你的命令是在反引号:
下你必须逃避它的原因"两次"是因为您在一个解释双引号字符串的环境(例如shell脚本)中输入此命令。然后由子shell再次解释。
自: