Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to make bash expand wildcards in variables?

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/.)

like image 201
Ross Duncan Avatar asked Jan 14 '11 14:01

Ross Duncan


People also ask

How do you expand a variable in bash?

Parameter expansion comes in many forms in bash, the simplest is just a dollar sign followed by a name, eg $a. This form merely substitutes the value of the variable in place of the parameter expansion expression. The variable name can also optionally be surround by braces, eg ${a}.

How do wildcards work in bash?

When we need to search for anything using shell commands then we need to define a pattern for searching. Wildcard characters are used to define the pattern for searching or matching text on string data in the bash shell. Another common use of wildcard characters is to create regular expressions.

What does $_ mean in bash?

$_ (dollar underscore) is another special bash parameter and used to reference the absolute file name of the shell or bash script which is being executed as specified in the argument list. This bash parameter is also used to hold the name of mail file while checking emails.

What is wildcard expansion?

Wildcard expansion can find all file names that end a certain way, but it can also find all file names that start a certain way.


2 Answers

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.

like image 105
Dennis Williamson Avatar answered Oct 07 '22 09:10

Dennis Williamson


You'll need to eval that line in order for it to work, like so:

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

Now, this has problems, in particular, if you don't trust $SUFFIXES, it might contain an injection attack, but for this simple case it should be alright.

If you are open to other solutions, you might want to experiment with find and xargs.

like image 28
falstro Avatar answered Oct 07 '22 09:10

falstro