8

使用 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但我希望这一切都可以以某种方式从外壳完成。

4

4 回答 4

19

...使用eval. 您要问的问题只能通过eval,您可能想要的内容很容易实现,而无需求助于 bash bug-central。

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

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

这正是您想要的,没有在此处的其他建议中引入和隐藏的数千个错误和安全问题。

它的工作方式是:

  • "${foo[@]}"foo:扩展通过扩展其每个元素命名的数组,并正确引用。不要忘记引号!
  • ${foo/a/b}: 这是一种参数扩展,它用 a 替换了第一个ainfoo的扩展b。在这种类型的扩展中,您可以使用%来表示扩展值的结束,有点像$正则表达式中的。
  • 将所有这些放在一起, "${foo[@]/%/ly}" 将扩展 的每个元素foo,将其正确引用为单独的参数,并将每个元素的结尾替换为ly.
于 2009-05-11T06:26:29.133 回答
3

在 bash 中,您可以这样做:

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

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

于 2009-05-11T04:51:49.910 回答
1

Zsh 可以轻松做到这一点:

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

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

quickly manly strongly
于 2013-09-19T12:16:05.520 回答
0

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

$ TEST=quick,man,strong
$ touch $(eval echo {$TEST}ly)
于 2009-05-11T05:08:11.757 回答