[repost] Howto Exclude Files From Wildcard Matches In bash

preface: This is a repost of an article I wrote more than ten years ago on our company homepage. Despite its age, the page still receives huge amounts of traffic and so I am reposting it here on my blog because the original article will vanish from our official company homepage soon.

Imagine you have a directory that contains several hundreds of files and for what reason ever you want to list all files in this directory except one or even worse a couple of them.

This sounds easy, but actually isn’t. Let me illustrate the situation:

Now say I want to get a listing of all files except confidential.txt. Of course, one could use sed or grep to do this but this is too much overhead as I don’t want to waste resources.

There are a couple of solutions all with certain drawbacks:

  •  Solution #1 – bad:

The expected result. But this version only works, if you have no more than one file starting with ‘c’ in the directory. Otherwise all files starting with a ‘c’ will be omitted. On the other hand, this can be used for any command that uses file globbing (such as cp and mv).

  •  Solution #2 – not so bad:

This gives us exactly the expected result. But however, this solution is bound to ls. If you want to do the same for cp or mv, you’re stuck again, because those commands have no idea of the –ignore switch.

  •  Solution #3 – good:

This turns on bash’es extended globbing features (shopt -s extglob) and as a result you can use !(something) to exclude “something” from a file globbing operation, which is used by any command that uses wildcards (such as cp and mv again).

You may have noticed that ‘!’ now has a different meaning (it is normally used to repeat old commands), which is its only drawback.

  •  Solution #4 – the best, IMHO:

GLOBIGNORE is a shell variable that allows to define certain patterns to identify things we don’t want to be displayed whenever wildcards are used. So if I said “GLOBIGNORE=”*secret*”, secret.txt and top_secret.txt would not have been listed. And this is my™ favourite.

Spread the love

Leave a Reply

2 Comment threads
2 Thread replies
Most reacted comment
Hottest comment thread
1 Comment authors
Udo RaderAdam RetchlessWilliam Morriss Recent comment authors
newest oldest most voted
Notify of
William Morriss

I think you have a typo in one of your files.

bash$ ls -l /opt/too_many_files/[c]*
Should be
bash$ ls -l /opt/too_many_files/[!c]*

Udo Rader

you are right, thanks for the tip!

Adam Retchless

Thanks for these tips. I have a follow up question for method 4 — when you are finished with what you are doing, how do you clear the GLOBIGNORE variable? Should I call “unset GLOBIGNORE” or is there a better option? Thanks.

Udo Rader

yes, “unset GLOBIGNORE” is the way to go here once you are finished.

Post Navigation