Can I do filename pattern matching in a bash script?

test is a directory with the following files ...

bob@bob-laptop:~/test$ ls  
exclude  exclude1  exclude2  include1  include2  

From the command line, if I want to exclude some of the files, I can do ...

bob@bob-laptop:~/test$ echo !(exclude*)  
include1 include2  

but, if I put that command in a script (named exclude) ...

bob@bob-laptop:~/test$ cat exclude  
echo !(exclude*)  

when I execute it, I get an error ...

bob@bob-laptop:~/test$ ./exclude  
./exclude: line 1: syntax error near unexpected token `('  
./exclude: line 1: `echo !(exclude*)'  

I've tried every (I think) variation of escaping some, all or none of the special characters and I still get an error.

What am I missing here? If I can't do this, would someone please be so kind as to explain why?


You need to put a shebang line at the top of the script. Without a shebang line, the kernel doesn't know that your script must be executed with bash. See Shell script fails: Syntax error: “(” unexpected

In addition, the !(…) syntax is not enabled by default, for historical reasons (earlier versions of bash did not support it). You need to set the extglob option.

shopt -s extglob
echo !(exclude*)
  • thanks very much! now I'm trying to figure out why I couldn't find this answer that was posted a mere two hours later – Bob Bowden Dec 25 '12 at 3:20
  • @BobBowden There is another answer on this question, posted about 2 hours earlier than mine and later deleted by its author. It is correct but less complete than my answer. – Gilles 'SO- stop being evil' Dec 25 '12 at 17:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.