Bash:用文件名中的空格扩展大括号和glob

前端之家收集整理的这篇文章主要介绍了Bash:用文件名中的空格扩展大括号和glob前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一些文件看起来像:
/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

猜你在找的Bash相关文章