how to make bash expand wildcards in variables?

Ross Duncan picture Ross Duncan · Jan 14, 2011 · Viewed 36.8k times · Source

I am trying achieve the same effect as typing

mv ./images/*.{pdf,eps,jpg,svg} ./images/junk/  

at the command line, from inside a bash script. I have:

MYDIR="./images"
OTHERDIR="./images/junk"  
SUFFIXES='{pdf,eps,jpg,svg}'
mv "$MYDIR/"*.$SUFFIXES "$OTHERDIR/"

which, when run, gives the not unexpected error:

mv: rename ./images/*.{pdf,eps,jpg,svg} to ./images/junk/*.{pdf,eps,jpg,svg}: 
No such file or directory

What is the correct way to quote all this so that mv will actually do the desired expansion? (Yes, there are plenty of files that match the pattern in ./images/.)

Answer

Dennis Williamson picture Dennis Williamson · Jan 14, 2011

A deleted answer was on the right track. A slight modification to your attempt:

shopt -s extglob
MYDIR="./images"
OTHERDIR="./images/junk"  
SUFFIXES='@(pdf|eps|jpg|svg)'
mv "$MYDIR/"*.$SUFFIXES "$OTHERDIR/"

Brace expansion is done before variable expansion, but variable expansion is done before pathname expansion. So the braces are still braces when the variable is expanded in your original, but when the variable instead contains pathname elements, they have already been expanded when the pathname expansion gets done.