【问题标题】:How can I do brace expansion on variables? [duplicate]如何对变量进行大括号扩展? [复制]
【发布时间】:2016-05-17 08:29:10
【问题描述】:

考虑以下脚本:

#! /bin/bash -e

echo {foo,bar}
EX={foo,bar}
echo ${EX}

这个脚本的输出是:

foo bar
{foo,bar}

我希望echo 命令对${EX} 执行大括号扩展。因此,我希望看到

的输出
foo bar
foo bar

我想创建一个脚本,用户可以在其中提供一个带有大括号的路径,复制它的每个扩展版本。

类似这样的:

#! /bin/bash -e

$SOURCES=$1
$TARGET=$2

cp -r ${SOURCES} ${TARGET}

我怎样才能做到这一点?

【问题讨论】:

  • cp -r foo bar foo bar 应该做什么?
  • 你也不能对变量进行大括号扩展,因为它是在它们之前评估的。
  • 不要让事情变得过于复杂。您编写一次脚本,然后多次使用它(可能)。因此,没有理由尝试节省。

标签: bash shell brace-expansion


【解决方案1】:

这是一种方式:

ex=({foo,bar,baz})
echo ${ex[@]}
foo bar baz

【讨论】:

  • 将值放入数组中与使用 brace-expansion 不同
  • @DavidC.Rankin 这实际上非常有效,您可以在其中放置多个大括号,然后它们会按照您的预期展开。
  • 在整个 bash 中都使用了大括号的嵌套功能。 去除子串的模式扩展就是一个很好的例子。
【解决方案2】:

man bash

扩展的顺序是:大括号扩展、波浪号扩展、参数、变量和算术扩展以及命令替换(以从左到右的方式完成)、分词和路径名扩展。

如您所见,变量扩展发生在大括号扩展之后。

幸运的是,您根本不需要它:让用户指定支撑路径,让 shell 扩展它们。然后你就可以了

mv "$@"

如果需要分离参数,使用数组和参数扩展:

sources=("${@:1:$#-1}")
target=${@: -1}
mv "${sources[@]}" "$target"

【讨论】:

  • 好建议 - 如果您接受已经扩展的参数,那么您的 shell 脚本的行为更像其他应用程序,并且用户可以以正常方式使用他们的 shell(而不是必须引用要被脚本覆盖)。
  • 为什么mv "$@" 大括号扩展在脚本中有效?什么 bash 构造使这成为可能。它与问题示例有何不同? (这不起作用)。
  • @mauron85:因为 shell 扩展了不带引号的大括号表达式,并且您的脚本获取了参数列表作为参数。
【解决方案3】:

大括号扩展无法按照您尝试使用的方式进行。大括号扩展基本上用于生成要在当前命令的上下文中应用的列表。您有两种直接使用大括号扩展的主要模式(以及更多使用大括号扩展作为另一个运算符的一部分的模式。)这两种直接用途是在 逗号分隔 中扩展项目列表一对大括号。例如

$ touch file_{a,b,c,d}.txt

执行命令后,大括号展开在当前目录中创建所有四个文件名格式正确的文件:

$ ls -1 file*.txt
file_a.txt
file_b.txt
file_c.txt
file_d.txt

您也可以以类似的方式使用 brace-expansion 来为循环迭代(或在需要生成的系统/数字范围的任何地方)生成列表。此处使用 大括号扩展 的语法类似,但在大括号内使用 .. 分隔符(而不是 ',' 分隔符)。语法为{begin..end..increment}(其中increment 可以是正数和负数)例如

$ for i in {20..-20..-4}; do echo $i; done)
20
16
12
8
4
0
-4
-8
-12
-16
-20

注意: 使用 beginendincrement 的变量是不允许的.

【讨论】:

    猜你喜欢
    • 2013-10-26
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多