| Author: Udo Rader |
| Creation date: 2003-08-24 |
Last revision: 2003-11-26 |
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:
bash$ ls -l /opt/too_many_files
secret.txt
top_secret.txt
confidential.txt
public.txt
|
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:
bash$ ls -l /opt/too_many_files/[^c]*
secret.txt
top_secret.txt
public.txt
|
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:
bash$ ls -l --ignore="confidential.txt" /opt/too_many_files
secret.txt
top_secret.txt
public.txt
|
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.
bash$ shopt -s extglob
bash$ ls -l /opt/too_many_files/!(confidential.txt)
secret.txt
top_secret.txt
public.txt
|
This turns on bashes 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 - best, IMHO:
bash$ GLOBIGNORE="confidential.txt"
bash$ ls -l /opt/too_many_files/*
secret.txt
top_secret.txt
public.txt
|
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(tm) favourite.
|