外壳中的棘手支撑扩展

时间:2009-05-11 04:44:32

标签: bash shell brace-expansion

使用POSIX shell时,如下

touch {quick,man,strong}ly

扩展为

touch quickly manly strongly

哪个会触及文件quicklymanlystrongly,但是可以动态创建扩展吗?例如,以下说明了我想要做的事情,但由于扩展的顺序不起作用:

TEST=quick,man,strong    #possibly output from a program
echo {$TEST}ly

有没有办法实现这个目标?如果需要,我不介意将自己限制在Bash。我也想避免循环。扩展应该作为任意程序的完整参数给出(即,对于每个文件不能调用一次程序,对于所有文件只能调用一次)。我知道xargs,但我希望它能以某种方式从shell中完成。

4 个答案:

答案 0 :(得分:18)

......使用eval有很多错误。只有eval才能实现您所要求的想要,而不必诉诸bash bug-central。

使用数组!每当您需要在一个数据类型中保留多个项时,您需要(或 使用)数组。

TEST=(quick man strong)
touch "${TEST[@]/%/ly}"

如果没有引入和隐藏在其他建议中的千个错误和安全问题,那就完全符合您的要求。

它的工作方式是:

  • "${foo[@]}":通过展开正确引用的每个元素来扩展名为foo的数组。不要忘记引号!
  • ${foo/a/b}:这是一种参数扩展,用a替换foo扩展中的第一个b。在此类扩展中,您可以使用%表示扩展值的结尾,类似于正则表达式中的$
  • 把所有这些放在一起,“$ {foo [@] /%/ ly}”将扩展foo的每个元素,正确引用它作为单独的参数,并用{{1}替换每个元素的结尾}。

答案 1 :(得分:3)

在bash中,你可以这样做:

#!/bin/bash
TEST=quick,man,strong
eval echo $(echo {$TEST}ly)
#eval touch $(echo {$TEST}ly)

最后一行已注释掉,但会触及指定的文件。

答案 2 :(得分:1)

Zsh很容易做到:

TEST=quick,man,strong
print ${(s:,:)^TEST}ly

变量内容以逗号分割,然后每个元素分布到大括号周围的字符串中:

quickly manly strongly

答案 3 :(得分:0)

从上面的答案中汲取灵感:

$ TEST=quick,man,strong
$ touch $(eval echo {$TEST}ly)