在 ZSH 中执行从字符串值到数组的大括号扩展

在 ZSH 中执行从字符串值到数组的大括号扩展

鉴于以下片段中概述的情况:

# Input string provided as function argument:
input='base/{local,remote,other}$(echo hi)'
# Desired result from performing just brace expansion of the above:
expected=('base/local$(echo hi)' 'base/remote$(echo hi)' 'base/other$(echo hi)')

ZSH中正确的执行方式是什么仅有的对任意用户定义的输入字符串进行大括号扩展并将结果参数数组存储到另一个变量中?我发现强制对值进行大括号扩展的唯一方法是使用eval,所以我想知道我所要求的是否可能?

一些研究表明以下方法可能有效,但事实似乎并非如此:

expanded=(${^input})
# Results in: expanded=('base/{local,remote,other}$(echo hi)')

答案1

如果您想要像在 shell 代码中找到它而不是其他形式的扩展一样进行该扩展,则没有运算符,因此您需要采用使用诸如eval引用除{, },之外的所有内容之后的方法。和,

也许是这样的:

set -o extendedglob
eval "expanded=( ${input//(#m)[^{\},]##/${(qq)MATCH}} )"

(请注意,即使使用引号,看起来{1..5}仍然会扩展,启用后的in..也是如此)。-{a-f}braceccl

上面没有处理转义,a\{x,y}扩展到a\x a\y和。a"{x,y}"a"x" a"y"

作为参考,请注意,如果bracexpand启用了该选项并且noglob未启用该选项(mksh 和最新版本的 ksh93 中的默认设置),ksh 将在未加引号的参数扩展或命令替换时执行大括号扩展。

对于 ksh93,禁用通配符的另一种方法是设置FIGNORE*,因此在 ksh93 中,您可以执行以下操作:

IFS= FIGNORE=*
expanded=( $input )

答案2

% x='{huh,what}'
% foo=( .(e:"reply=($x)":) )
% print -Rl $foo
huh
what

呃,这可能太聪明了,因为它滥用了eglob 求值器,用插值大括号扩展替换(被忽略的)glob 结果。

相关内容