正确使用〜参数扩展标志?

时间:2014-08-31 14:19:20

标签: zsh

根据man zshexpn(5.0.2):

  

〜强制将字符串参数连接到括号内的下面任何标志,以作为                 图案。

例如,使用s标志执行字段拆分需要字符串参数:

% print -l ${(s:9:):-"foo893bar923baz"}
foo8
3bar
23baz

我对~标志的阅读表明我应该能够指定一个模式来代替要分割的文字字符串,以便以下

% print -l ${(~s:<->:):-"foo893bar923baz"}

应该产生

foo
bar
baz

相反,它的行为与我省略~的行为相同,完全不执行拆分。

% print -l ${(s:<->:):-"foo893bar923baz"}
foo893bar923baz
% print -l ${(~s:<->:):-"foo893bar923baz"}
foo893bar923baz

1 个答案:

答案 0 :(得分:1)

好的,重读这个问题,这就是它之间的区别:

$ val="foo???bar???baz" 
$ print -l ${(s.?.)val}
foo
bar
baz

而且:

$ val="foo???bar???baz" 
$ print -l ${(~s.?.)val}
foo???bar???baz

它对变量进行操作,即拆分的“参数”(来自文档引用)。在第一个例子中,我们替换文字?,在第二个例子中,我们将变量视为glob,并且没有文字?,因此没有任何内容被替换。

尽管如此,从documentation

开始,拆分工作在字符而不是替换本身的整体中。
s:string:
    Force field splitting (see the option SH_WORD_SPLIT) at the separator string.

所以,看起来你不能分裂模式。 ~字符修改要拆分的字符串的解释。

此外,从您引用的相同模式扩展文档中,它会继续:

  

比较〜外部括号,强制整个   替换字符串作为模式处理。 [[ "?" = ${(~j.|.)array} ]]   如果和,则使用EXTENDED_GLOB选项设置成功   只有当$ array包含字符串'?'作为元素时。争论可能   重复切换行为;它的效果只会持续到最后   括号内的小组。

${(~j.|.)array}${(j.|.)~array}之间的区别在于前者将array中的值视为全局值,而后者将结果视为glob。

另见:

  

${~spec}打开GLOB_SUBST选项以评估规范;如果   '〜'加倍,将其关闭。设置此选项后,将显示该字符串   由扩展产生的结果将被解释为任何地方的模式   这是可能的,例如在文件名扩展和文件名中   生成和模式匹配上下文,如右侧   条件中的'='和'!='运算符。

这是一个显示差异的演示:

$ array=("foo???bar???baz" "foo???bar???buz")
$ [[ "foo___bar___baz" = ${(~j.|.)array} ]] && echo true || echo false
false
$ [[ "foo___bar___baz" = ${(j.|.)~array} ]] && echo true || echo false
true

为了完整性:

$ [[ "foo___bar___baz" = ${(~j.|.)~array} ]] && echo true || echo false
true