Shell – ls, regexp and environment variable

shellwildcards

I wanted to declare an environment variable that stocks all the extensions of video files so I can use it when using the shell.

I tried several things but never got it to work:
If in my .bash_profile I put:

export VIDEOS={mp4,wmv,avi,flv,mkv,m4u,mpg,mpeg}

it only takes the last element:

[nbarraille@nbarraille ~]echo $VIDEOS
mpeg

If in my .bash_profile I put:

export VIDEOS="{mp4,wmv,avi,flv,mkv,m4u,mpg,mpeg}"

or

export VIDEOS='{mp4,wmv,avi,flv,mkv,m4u,mpg,mpeg}'

Then, when I display it it looks OK, but it doesn't work when I use it in a ls for example:

[nbarraille@nbarraille ~] echo $VIDEOS
{mp4,wmv,avi,flv,mkv,m4u,mpg,mpeg}
[nbarraille@nbarraille ~] ll *.$VIDEOS
ls: cannot access *.{mp4,wmv,avi,flv,mkv,m4u,mpg,mpeg}: No such file or directory

And when I run the exact same command without using the variable, it works:

[nbarraille@nbarraille ~] echo *.{mp4,wmv,avi,flv,mkv,m4u,mpg,mpeg}
example.avi
example2.mpg

Also, when I reboot, it looks like my .bash_profile is not loading, and the $VIDEOS variable is empty. I have to do a source ~/.bash_profile in order to get it to work (and I have to redo so every time I open a new terminal.

Any idea?

Thanks!

Best Answer

Your command is being expanded to this:

export VIDEOS=mp4 VIDEOS=wmv VIDEOS=avi VIDEOS=flv VIDEOS=mkv VIDEOS=m4u VIDEOS=mpg VIDEOS=mpeg

Run this to see what's happening:

echo export VIDEOS={mp4,wmv,avi,flv,mkv,m4u,mpg,mpeg}

(it's called brace expansion)


The second problem is that bash does brace expansion before parameter expansion, not after it, so anything that looks like your solution will be messy.

You would have to do something like this:

eval echo \*.$VIDEOS

which will get annoying to type every time.

How about something like this:

videos() {
    find . -mindepth 1 -maxdepth 1 -type f \
        \( -name "*.mp4" -o -name "*.wmv" -o -name "*.avi" -o \
           -name "*.flv" -o -name "*.mkv" -o -name "*.m4u" -o \
           -name "*.mpg" -o -name "*.mpeg" \)
}

Then instead of doing:

ls *.$VIDEOS

just do this:

videos

or if you need to pass it to a command:

ls $(videos)

This part working:

echo *.{mp4,wmv,avi,flv,mkv,m4u,mpg,mpeg}

could be the clue to .bash_profile not working. For example, it might mean you are using zsh.

Please tell us what this does:

echo $0

so we can figure out which file you have to put it in.

Related Question