Bash: Expand braces and globs with spaces in filenames?

℡╲_俬逩灬. 提交于 2019-12-01 16:35:01

To perform brace expansion and globbing on a path with spaces, you can quote the portions of the path that contain spaces, e.g.

mycmd '/path/with spaces/'{a,b,c}/*.gz

Doing brace expansion using a list of values from a variable is a little tricky since brace expansion is done before any other expansion. I don't see any way but to use the dreaded eval.

eval mycmd "'/path/with spaces/'{a,b,c}/*.gz"

P.S. In such a case however, I would personally opt for a loop to build the argument list rather than the approach shown above. While more verbose, a loop will be a lot easier to read for the uninitiated and will avoid the need to use eval (especially when the expansion candidates are derived from user input!).


Proof of concept:

Using a dummy command (x.sh) which prints out the number of arguments and prints out each argument:

[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
Jay Hacker

Okay, so here is one using bash for the "braces" and find for the globs:

find "${dirs[@]/#//path/with spaces/}" -name '*.gz' -print0 | xargs -0 mycmd

Useful with this if you need the results in an array.

Here's one for the GNU Parallel fans:

parallel -Xj1 mycmd {}/*.gz ::: "${dirs[@]/#//path/with spaces/}"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!