如何以特定顺序生成包含扩展的列表?

时间:2013-08-02 11:21:23

标签: bash zsh

我知道如何以这种方式轻松生成列表:

echo {a,b,c,d}_{0..3}

将给出:

a_0 a_1 a_2 a_3 b_0 b_1 b_2 b_3 c_0 c_1 c_2 c_3 d_0 d_1 d_2 d_3

但是如何生成相同的列表,但第二个大括号的优先级更高,以获得这个? :

a_0 b_0 c_0 d_0 a_1 b_1 c_1 d_1 a_2 b_2 c_2 d_2 a_3 b_3 c_3 d_3

任何技巧,例如从最后排序,或从字符 n 排序都可以,只要它适合一行。我也在使用zsh,但是使用bash的东西很好。

5 个答案:

答案 0 :(得分:7)

这没有实现,但你可以使用像

这样丑陋的黑客
echo $(eval echo \{a,b,c,d\}_{0..3})

通过积极地首先评估后一个支撑来实现它,并且在第二步中首先支撑第一个支撑。

请记住,虽然中间步骤必须足够小,以便shell仍然可以解析; - )

答案 1 :(得分:2)

我想用另一种方法添加另一种解决此问题的方法。它基于转动表达式,然后对其进行评估,然后再将结果转回:

eval echo $(echo '{a,b,c,d}_{0..3}' | rev | tr '{}' '}{') | rev

结果

a_0 b_0 c_0 d_0 a_1 b_1 c_1 d_1 a_2 b_2 c_2 d_2 a_3 b_3 c_3 d_3

但我不确定我是否真的可以这样做; - )

答案 2 :(得分:2)

不是严格的内部攻击,但

printf "%s\n" {a,b,c,d}_{0..3} | sort -t_ -k2,2n

答案 3 :(得分:2)

我还找到了另一个解决方案(仅限zsh),不必要的复杂,因此很有趣:

print {a,b,c,d}_${^=${$+0 1 2 3}}

这里做什么zsh?它从最后一个嵌套大括号开始:

  • 检查是否存在$$,因此请使用" 0 1 2 3" (运营商+)
  • 将其拆分为数组(operator =)
  • 将每个元素的分布应用于字符串,如大括号扩展(operator ^)
  • 最后应用第一个撑杆的扩展(因为撑杆扩展的优先级低于参数扩展)

请注意,我必须自己展开{0..3},因为没有标记/运算符可以触发此类AFAIK的初步扩展(eval除外,如上所述)。

答案 4 :(得分:0)

eval echo \{a..d\}_{0..3}

就够了

第一次扩展 - 由shell--是

{a..d}_0 {a..d}_1 {a..d}_2 {a..d}_3
那么eval的第二次扩张就是

a_0 b_0 c_0 d_0 a_1 b_1 c_1 d_1 a_2 b_2 c_2 d_2 a_3 b_3 c_3 d_3

结果发送到stdout。