例如{a..c}{1..3}
扩展为a1 a2 a3 b1 b2 b3 c1 c2 c3
。
如果我想打印a1 b1 c1 a2 b2 c2 a3 b3 c3
,是否有类似的方法可以做到?最简单的方法是什么?
例如{a..c}{1..3}
扩展为a1 a2 a3 b1 b2 b3 c1 c2 c3
。
如果我想打印a1 b1 c1 a2 b2 c2 a3 b3 c3
,是否有类似的方法可以做到?最简单的方法是什么?
Answers:
您可以这样做:
$ eval echo '{a..c}'{1..3}
a1 b1 c1 a2 b2 c2 a3 b3 c3
然后告诉外壳评估:
echo {a..c}1 {a..c}2 {a..c}3
对于这种特殊情况,我认为StéphaneChazelas提供的选择是最好的选择。
另一方面,当您扩展更复杂的内容时,此选项无法很好地扩展。因此,您可以使用以下方法实现相同的目的:
$ printf '%s\0' {a..c}{1..3} | sort -zk 1.2,1.2 | tr '\0' ' '
返回:
a1 b1 c1 a2 b2 c2 a3 b3 c3
似乎有些混乱,但是现在,我在命令中有了一个很大的控制权,只是在上面的命令中更改了两个字符;例如:
$ echo {a..b}{1..2}{a..b}{1..2}
这将扩展为:
a1a1 a1a2 a1b1 a1b2 a2a1 a2a2 a2b1 a2b2 b1a1 b1a2 b1b1 b1b2 b2a1 b2a2 b2b1 b2b2
假设我要1
在第二个扩展中全部使用,然后是2
:
$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.2,1.2 | tr '\0' ' '
a1a1 a1a2 a1b1 a1b2 b1a1 b1a2 b1b1 b1b2 a2a1 a2a2 a2b1 a2b2 b2a1 b2a2 b2b1 b2b2
假设我要a
在第三个扩展中添加所有内容,然后是b
:
$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.3,1.3 | tr '\0' ' '
a1a1 a1a2 a2a1 a2a2 b1a1 b1a2 b2a1 b2a2 a1b1 a1b2 a2b1 a2b2 b1b1 b1b2 b2b1 b2b2
假设我要1
在第四个扩展中添加所有内容,然后是2
:
$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.4,1.4 | tr '\0' ' '
a1a1 a1b1 a2a1 a2b1 b1a1 b1b1 b2a1 b2b1 a1a2 a1b2 a2a2 a2b2 b1a2 b1b2 b2a2 b2b2
假设我要在所有1a
中间1b
,然后是2a
,然后是2b
:
$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.2,1.3 | tr '\0' ' '
a1a1 a1a2 b1a1 b1a2 a1b1 a1b2 b1b1 b1b2 a2a1 a2a2 b2a1 b2a2 a2b1 a2b2 b2b1 b2b2
您甚至可以轻松地颠倒上述扩展中的任何顺序,只需r
在前面的命令中添加一个即可。例如,最后一个:
$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -rzk 1.2,1.3 | tr '\0' ' '
b2b2 b2b1 a2b2 a2b1 b2a2 b2a1 a2a2 a2a1 b1b2 b1b1 a1b2 a1b1 b1a2 b1a1 a1a2 a1a1
注意_1:通常,如果此最终扩展将用作参数列表,则尾随空格不是问题;但是,如果要删除它,可以将其添加到上述任何命令中,例如| sed 's/ $//'
;甚至| sed 's/ $/\n/'
改变尾随空间newline
注意_2:在上面的示例中,为简单起见,我使用了两个元素的子集(即 {a,b}和 {1,2}):您可以使用任何有限长度的子集,而相应的命令,将是可比的。
一个可以在(bash,ksh,zsh)中工作的衬板(并非所有shell都可以按相反的顺序进行“括号扩展”):
$ echo {3..1}{c..a} | rev
a1 b1 c1 a2 b2 c2 a3 b3 c3
可以使用的替代方法eval
(仍然适用于bash,ksh,zsh,并且可能更含糊)是:
$ eval echo '{a..c}'{1..3}
a1 b1 c1 a2 b2 c2 a3 b3 c3
要了解会发生什么,请替换eval
为echo
:
$ echo echo '{a..c}'{1..3}
echo {a..c}1 {a..c}2 {a..c}3
(在eval扩展之后)执行的命令实际上是echo {a..c}1 {a..c}2 {a..c}3
。它会根据您的需要扩展。
有几个没有“括号扩展”的shell,因此,不可能将其用于“所有shell”。我们需要一个循环(尾随空白):
$ for i in 1 2 3; do for j in a b c; do printf "%s%s " "$j" "$i"; done; done; echo
a1 b1 c1 a2 b2 c2 a3 b3 c3
如果您必须没有添加尾随空间:
s=""
for i in 1 2 3; do
for j in a b c; do
printf "%s%s%s" "$s" "$j" "$i"
s=" "
done
done
echo
版画
a1 b1 c1 a2 b2 c2 a3 b3 c3
如果您需要对许多值执行此操作,则需要使用与括号扩展类似的方法来生成数字列表$(seq 10)
。并且,由于seq无法生成字母列表,因此我们需要将生成的数字转换为ascii:
s=""
for i in $(seq 4); do
for j in $(seq 5); do
printf "%s\\$(printf %03o $((96+j)))%s" "$s" "$i"
s=" "
done
done
echo
印刷品:
a1 b1 c1 d1 e1 a2 b2 c2 d2 e2 a3 b3 c3 d3 e3 a4 b4 c4 d4 e4
yash -o braceexpand -c 'echo {3..1}{c..a}'
打印3{c..a} 2{c..a} 1{c..a}
。没有完全的“扩张”。
{a..c}1 {a..c}2 {a..c}3
括号中{a..c}{1..3}
的扩展从左到右扩展,因此您首先得到a{1..3} b{1..3} c{1..3}
,然后将字母与数字组合成a1 a2 a3 b1 b2 b3 c1 c2 c3
。要获得所需的订单,您将不得不使用上面稍长的表达式。
这适用于您的简单情况,可以扩展,但是很快就会失去控制。更复杂的情况是不容易解决的。
颠倒括号扩展的顺序,然后交换字符:
echo {1..3}{a..c} | sed -E 's/(.)(.)( ?)/\2\1\3/g'
通过以下方法完成
for i in {1..10}; do for j in {a..c}; do echo $j$i; done; done| perl -pne "s/\n/ /g"
输出
a1 b1 c1 a2 b2 c2 a3 b3 c3 a4 b4 c4 a5 b5 c5 a6 b6 c6 a7 b7 c7 a8 b8 c8 a9 b9 c9 a10 b10 c10
for i in {1..10}; do for j in {a..c}; do printf '%s ' "$j$i"; done; done;echo
yash -o braceexpand
到列表中。