我有一些文件看起来像:
/path/with spaces/{a,b,c}/*.gz
而且,我需要所有与a,c dirs子集匹配的文件,作为单个命令的参数:
mycmd '/path/with spaces/a/1.gz' '/path/with spaces/a/2.gz' '/path/with spaces/c/3.gz' ...
我关心的目录作为命令行参数进入,我有一个数组:
dirs=( "$@" )
我想做一些像:
IFS=,mycmd "/path/with spaces/{${dirs[*]}}/"*.gz
但是这不起作用,因为bash在变量之前扩展了大括号.我已经尝试过使用echo和ls,甚至eval(* shudder *)的技巧,但是很难让它们与文件名中的空格一起使用.发现似乎没有太大的帮助,因为它不做大括号.我可以在数组中为每个目录获取一个单独的glob:
dirs=( "${dirs[@]/#//path/with spaces/}" ) dirs=( "${dirs[@]/%//*.gz}" )
但随后bash引用通配符扩展.
那么,有没有一个优雅的方式来获取所有的文件匹配一个可变的大括号和glob模式,正确处理空间,或者我卡住了循环?我使用Bash 3,如果这有所作为.
要在具有空格的路径上执行扩展和扩展,您可以引用包含空格的路径部分,例如.
mycmd '/path/with spaces/'{a,c}/*.gz
使用变量值的列表进行大括号扩展有点棘手,因为在任何其他扩展之前完成扩展.我看不到任何方式,但使用可怕的eval.
eval mycmd "'/path/with spaces/'{a,c}/*.gz"
附:然而,在这种情况下,我会亲自选择循环来构建参数列表,而不是上面所示的方法.虽然更冗长,但是对于未启动的循环将会更容易阅读,并且将避免使用eval(特别是当扩展候选者来源于用户输入时).
概念证明:
使用一个虚拟命令(x.sh),打印出参数的数量并打印出每个参数:
[me@home]$shopt -s nullglob # handle case where globbing returns no match [me@home]$./x.sh 'path with space'/{a,b}/*.txt Number of arguments = 3 - path with space/a/1.txt - path with space/b/2.txt - path with space/b/3.txt [me@home]:~/temp$dirs="a,b" [me@home]k:~/temp$eval ./x.sh "'path with space'/{$dirs}/*.txt" Number of arguments = 3 - path with space/a/1.txt - path with space/b/2.txt - path with space/b/3.txt