Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I know some regex but I don't know how to get this to work. I want to list all files that don't have .tab. and don't have ~ at the end of the filename and aren't a .o (or .bin)

I can list all the files that have .tab. by writing

ls | grep .tab.

However I cannot figure out how to make it ignore those files and list everything else. I tried

ls | grep [^(.tab.)]

but got an error and thought my final regex would be

ls | grep ([^(.tab.)]|.o$|.bin$)

But I've never done much regex so I am sure the final is wrong even if the syntax was right.

share|improve this question
up vote 4 down vote accepted

How I would do this would depend on the context. If this wasn't for a script, and I just wanted to see this, I would be okay with using ls:

ls -a | egrep -v '(tab|\.o$|\.bin$|~$)'

If in a script, I would use a loop:

for file in *; do
#file $file in .* *; do   -- To Include dot (hidden files)                     
   if ! egrep -q '(tab|\.o$|\.bin$|~$)' <<<$file; then
      echo $file

You could add another if test with -f if you only want regular files and not directories. If you want to do this recursively, you could use GNU find with a -regex test and posix-egrep. But take into account the fact that this regex will match the full pathname relative to the directory you searched in.

Another nice option is extended globs if you have support for it, see Dennis's answer.

share|improve this answer
You can also use fancy =~ regex tests with certain shells, really, there are tons of ways to do this :-) – Kyle Brandt Oct 23 '09 at 13:15

ls | egrep -v (.tab|.o$|.bin$)

should do it. egrep is basically grep -E, which supports 'extended' regex, so stuff like (x|y) works.

share|improve this answer
Need to escape the dots, this would exclude files such as '' – Kyle Brandt Oct 23 '09 at 13:03
You're correct, that's what I get for doing regex before coffinating myself ;) – Marcin Oct 23 '09 at 13:46
Ha ha fool! I never post before my second cup! glugglugglug – Satanicpuppy Oct 23 '09 at 14:05
Definitions, just in time for Halloween: "coffinating" - What a vampire does just before sunrise. "coffeenating" - What a vampire does just before going to "work" (euphamistically speaking). – Dennis Williamson Oct 23 '09 at 17:26
Umm...I did that on purpose, in the spirit of Halloween ;) I seriously need more coffee... – Marcin Oct 23 '09 at 18:16

The -v/--invert-match option makes grep output lines that do not match. So:

ls | grep -v .tab.


ls | grep --invert-match .tab.

in your case.

share|improve this answer
shopt -s extglob
ls -l !(*.bin|*.o|*~|*.tab.*)
share|improve this answer
This is Bash-specific. In ksh, no option needs to be set. For zsh you need to do setopt kshglob. – Dennis Williamson Oct 23 '09 at 13:07

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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