Bash tilde *substring* expansion - 未记录的功能?

7
我很惊讶这个扩展:
$ echo "${foo:~abc}"

foo未设置时,返回了空字符串。我预期它应该像这样解析:
$ echo "${foo:(~abc)}"

并且产生字符串“~abc”。但是,我发现如果我确实定义了
$ foo='abcdefg'
$ echo "${foo:~abc}"
g

事实上,它在算术环境中接受"abc"并执行"${foo:~0}"。同样地。
$ foo='abcdefg'
$ echo "${foo:~3}"
defg

它可以获取扩展的最后n+1个字符。我查看了manpage中的“参数扩展”部分,没有提到波浪号。Bash Hackers Wiki只将波浪号作为(同样未记录的)case修饰符进行提及。
这种行为至少可以追溯到3.2.57版本。
我是不是错过了这种子字符串扩展形式的文档,还是根本没有文档记录?

1
由于 :~ 不存在,我猜它会被解析为 ${parameter:offset:length} 子字符串扩展,因为它在语法上最接近,尽管 offset 得到了奇怪的值。这就是为什么你得到了一个子字符串。文档在 Bash 参考手册的“Shell 参数扩展” 章节中。 - KurzedMetal
1个回答

8

这并不是未记录的(您可能将${foo:~abc}${foo-~abc}混淆了)。

${parameter:offset}
${parameter:offset:length}
     Substring Expansion.  Expands to up to length characters of  the
     value  of  parameter starting at the character specified by off-
     set.  [...]  If length is omitted, expands to the  substring  of  the
     value of parameter starting at the character specified by offset
     and extending to the end of the value.  length  and  offset  are
     arithmetic expressions (see ARITHMETIC EVALUATION below).

在这里,~abc是扩展的偏移字段,~是算术表达式中的按位取反运算符。在算术表达式中,未定义的参数将被评估为0,~0 == -1


处理得很好。我刚意识到它似乎以某种方式“反转”了数字,但尚未弄清楚如何。 - Etan Reisner
啊,我把这个解析的过程想得太神秘了。谢谢! - kojiro

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