根据我的理解,\n
应该被解释为
"a\nb"
$'a\nb'
但不在
'a\nb'
但是,我看到以下内容:
(来自我的zsh会话的transsscript)
-0-1- ~ > zsh --version
zsh 5.1.1 (x86_64-unknown-cygwin)
-0-1- ~ > echo 'a\nb'
a
b
-0-1- ~ >
答案 0 :(得分:4)
zsh
本身并不解释\n
中的'a\nb'
,但内置echo
会解释'a\nb'
。 "a\nb"
和\n
是等效的,不包含换行符,而是包含(文字)字符序列$'a\nb'
。另一方面,zsh
确实包含换行符。
这里有两件事情可以解决:
引用用于告诉shell您想要一个字符本身,而不是它在shell语法中可能具有的任何特殊含义。 \
有四种类型的引用,其中一些可能会保留或为几个字符或字符序列添加特殊含义:
\
:通过预先zsh
引用单个字符。对于\n
来说,n
仅表示“我想要角色n
”。由于n
没有特殊含义,因此与仅编写*
相同。这更改为*
之类的字符:没有引用\*
被用作通配符的通配符,写echo /*
会阻止它(例如:比较echo /\*
和{{1的输出}})。如果您想直接传递字符\
,则必须引用它,例如使用其他\
:\\
。'...'
:与\
一样,任何带有'...'
的字符都是字面意思,这包括其他引用方法。 'foo* bar?'
基本上等同于foo\*\ bar\?
(或\f\o\o\*\ \b\a\r\?
,如果一个人想要迂腐)。只有'
本身不能出现在引用'...'
的字符串中,因为它会标记qoute的结尾。 (可以通过设置RC_QUOTES
来更改。如果设置一对单引号作为单引号:'foo''bar'
→foo\'bar
)"..."
:允许参数和命令替换。这意味着将$
之后的单词作为参数名称(例如"path: $PATH"
),并将$(...)
或`...`
中包含的字符串用于命令替换(例如echo "Date: $(date)"
)。否则,它的行为类似于'...'
,但允许引用`
,$
,\
和"
以及\
。$'...'
:字符串insid $'...'
被视为print
内置的字符串参数。只有在这里,一些字母字符确实具有特殊含义:换行符\n
,退格行为\b
,钟声字符\a
等。\
和'
可以分别引用\\
和\'
。结果字符串被视为完全引用。 $'...'
内有 no 参数或命令替换。echo
:除了echo
二进制文件或bash-builtin echo
之外,zsh-builtin默认识别(某些)转义序列,如\n
或\t
。虽然这种行为通常需要使用/bin/echo
或bash-builtin显式启用(通常通过传递-e
标志:echo -e "foo\nbar"
),但对于zsh-builtin,需要明确禁用。通过传递-E
标记(echo -E 'foo\nbar'
)或设置BSD_ECHO
选项(setopt bsdecho
),在这种情况下-e
标记可用于重新启用与其他类型的echo
一样的功能。
这意味着'a\nb'
和"a\nb"
(以及a\\nb
这个问题)都会以a\nb
(字面意思)传递,但是zsh-builtin {{1}然后解释echo
,导致带换行符的输出。另一方面,\n
在传递给$'a\nb'
之前已包含文字换行符。
运行
echo
应该得到以下输出:
for quoted_string in a\\nb 'a\nb' "a\nb" $'a\nb'; do
echo '>' $quoted_string '<'
/bin/echo -e '>' $quoted_string '<'
echo -E '>' $quoted_string '<'
/bin/echo '>' $quoted_string '<'
echo
done
正如您所看到的,前三种引用之间没有区别,而第四种始终使用换行符打印。
BTW:> a
b <
> a
b <
> a\nb <
> a\nb <
> a
b <
> a
b <
> a\nb <
> a\nb <
> a
b <
> a
b <
> a\nb <
> a\nb <
> a
b <
> a
b <
> a
b <
> a
b <
(至少版本5;我不知道Perl 6)的行为与描述预期行为的方式有关。 perl
perl
中的行为与'...'
中的行为相同。另一方面,zsh
中"..."
的行为类似于perl
"..."
$'...'
的组合:变量被其值和字符序列替换为{{} 1}}和zsh
是专门处理的。
答案 1 :(得分:2)
你错误的"a\nb"
,不用换行符替换\n
(好吧,不管怎样)。因此,没有标准的引用机制允许字符串中的换行符而不使用文字换行符,如
x="a
b"
这就是发明$'a\nb'
符号的原因。截至2016年,它不是POSIX,但POSIX人员正在考虑将其添加到shell specification。一如既往,不要屏住呼吸: - )
答案 2 :(得分:0)
新行是字符,而不是变量,因此没有解释(或扩展)。如果要打印\
,则需要将其转义两次,以表示您不想转义不想打印特殊字符的变量和。
所以你必须使用echo a\\\\nb
或echo 'a\\nb'