Bash中非数字或字母的范围

3

今天我尝试使用bash的{..}结构。我知道

{a..z}

会生成所有字母,

{0..9}

数字等(显然是数字),但我不小心拿到了

{Z..a}

yielding:

Z [  ] ^ _ ` a

在ASCII码表中,位于字母“Z”(90)和“a”(97)之间的字符是ASCII 91-96。敏锐的读者会注意到有一个字符缺失——反斜杠“\”,92。我猜测这是因为它的特殊性质所致。这是否是输出的预期行为?具体来说,我猜测\被用来转义其后面的空格,但@John1024指出:
echo {Z..a}a

没有引号的上一个版本不会报错,而现在这个版本则会因缺失引号而报错。具体是如何进行替换的?是否存在错误?

其次,我猜测区间运算符比我想象中更强大,并且可以选择任意ASCII字符范围,但例如 {[.._} 会失败。我是否遗漏了一些东西让它能够工作,还是说这只是一个好奇心实验? 除了字母和数字之外,还有哪些区间可以使用?如果没有,为什么不能对于从大写跳转到小写的情况什么也不做(失败,并按原样输出)?

2个回答

4

\会被生成;然而,它随后似乎被视为转义了下一个空格。比较:

$ printf '%s\n' 'Z' '[' ']' '^' '_' '`' 'a'
Z
[
]
^
_
`
a
$ printf '%s\n' {Z..a}
Z
[

]
^
_
`
a

[后面的额外空行是由{Z..a}生成的反斜杠转义的空格。


1
非常好。此外,请注意 echo {Z..a}a 会生成错误 bash: bad substitution: no closing "\" in a,这表明反引号在此形式中是一个活动字符,即使在形式 echo {Z..a}` 中它是 活动的。 - John1024
“{[.._}” 为什么无法正常工作?花括号扩展中使用的字符只能是字母和数字吗? - PesaThe
1
@PesaThe man bash说:“字符必须是相同类型的。” 就我所知,然而,单词“类型”未明确定义,但它可能意味着bash想要数字或字母。 - John1024
我已经了解了,但我想知道事物的顺序。@John1024 为我解决了问题 - 首先替换范围,然后原样使用结果(我手动输入的),这应该是预期的行为。有没有人有证据可以解释为什么只有字母/数字有效?我想知道是否进行了字母数字检查,但输出仅基于ASCII码。 - kabanus
@John1024 我重新阅读了你的第一条评论,现在我明白了。看起来其中一个行为是意外的(没有'a'应该会抱怨?),所以这是一个bug吗? - kabanus
显示剩余3条评论

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接