【问题标题】:Zsh parameter expansionzsh参数扩展
【发布时间】:2018-11-08 20:47:22
【问题描述】:

如何让以下 z shell 脚本以与 bash 中相同的方式运行?

for x in {f..k}
    do echo ${x}
done

在 bash 中我得到 f j k 打印出来,但在 zsh 中,我得到 {f..k} 字面打印。

编辑

我真正想做的(最初应该提到这一点)是:

FIRSTLETTER=a
LASTLETTER=b
for x in {$FIRSTLETTER..$LASTLETTER}
do 
    echo "/dev/sd${x}1"
done

【问题讨论】:

标签: bash zsh


【解决方案1】:

bash 中,大括号扩展发生在参数扩展之前。结果是{$FIRSTLETTER..$LASTLETTER} 不受大括号扩展的影响,因为它不是有效的序列表达式:

序列表达式采用 {x..y[..incr]} 形式,其中 x 和 y 是 整数或单个字符

只有这样文字字符串才会进行参数扩展,产生单个单词{a..b}

zsh 中,大括号扩展发生在其他几种扩展类型(包括参数扩展)发生之后。因此,{$FIRST_LETTER..$LAST_LETTER} 扩展为 {a..b},然后进行大括号扩展以生成 a b

最终结果是你所做的应该在zsh 中工作,而不是在bash 中。此外,如果不使用eval,则无法在bash 中执行您想要的操作。

for x in $(eval "echo {$FIRSTLETTER..$LASTLETTER}")

请记住,这是脆弱的,需要您非常确保这两个参数只能扩展为单个字母。

【讨论】:

  • 这绝对成功了。谢谢你的解释。
【解决方案2】:

有效:

for x ({f..k}); echo ${x}

【讨论】:

  • 仍然得到 {f..k} 作为输出。
  • 也许考虑使用更新版本的 zsh?我的是 zsh 5.3.1
  • 看来 5.0.2 是 RHEL7 的最新版本
【解决方案3】:

没有方便的 zsh,只是尝试一种解决方法。它会这样做吗?

for o in $(seq 102 107)
do x=$(printf %x $o)
   printf "\x$x"
done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 2011-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多