嵌套大括号扩展和命令替换

嵌套大括号扩展和命令替换

我想创建一个简单的 bash 脚本来检查目录是否包含名称包含从 1 到 N 的数字的所有文件。

# Creating some files for testing
$ cd /tmp/
$ mkdir test
$ touch test/a01x.dat
$ touch test/b02y.dat

# Display dir contents
$ ls test/*{01,02}*
test/a01x.dat  test/b02y.dat

但使用seq命令生成数字会产生以下结果:

$ ls test/*{$(seq -s , -f "%02g" 1 2)}*
ls: cannot access 'test/*{01,02}*': No such file or directory

我知道通过用单引号引起来的路径来运行命令一定会导致错误,因为通配符不会扩展

$ ls 'test/*{01,02}*'

但我没有使用它们。问题是什么?

答案1

问题是 shell 会{...,...}在进行命令替换($(...)部分)之前进行大括号扩展(处理 )。因此,在seq扩展 your 后,shell 不会重新计算 ,{01,02}并将其保留为文字。

您需要添加一个eval以使其在执行命令替换后重新计算表达式:

$ eval "ls test/*{$(seq -s , -f "%02g" 1 2)}*"

在这种情况下,将首先执行命令替换,生成一个字符串ls test/*{01,02}*,然后eval要求 shell 将其解释为命令,然后执行大括号和全局扩展,生成您期望的文件列表。

相关内容