tags:

views:

54

answers:

5

can anyone help me with a regex that will find files that dont have a .tar.gz extension

i need it to work in my unix script

for i in <REGEX for non tar.gx files>
do
something
done

thanks

+3  A: 

Never, never, never use regexes for the task "match every X that doesn't match Y". Instead, use the trivial regex for X and negate the result.

(In shell expressions, replace == with != , or use grep -v . In Perl, use !~ instead of =~ . In JQuery, use the :not operator, etc. If your API doesn't allow you to do anything else but specify one single regex, beat the vendor over the head with Chomsky's A hierarchy of formal languages.)

Complemented regexes are always either inefficient, unreadable or engine-specific - usually all of the above. Just say no to abuse of regexes, use tools for the tasks they're good at!

Kilian Foth
+3  A: 

In bash, with extglob turned on (which appears to be the default) you can negate a glob by using !(<glob>). So:

for i in !(*.tar.gz)
do
    something
done

If you wanted to match two globs, you'd write for i in *.tar.gz *~. Similarly, you can write for i in !(*.tar.gz|*~) if you want to match all files that are neither gzipped archives nor backup files.

Andrew Aylett
+1  A: 

If you don't want to use extended globbing, you can also include a simple test:

for file in *
do
    if [[ $file != *.tar.gz ]]
    then
        something
    fi
done
Philipp
+1  A: 

Another possibility (which illustrates an often-overlooked technique) is simply:

ls | grep -v 'pdf$'|while read i; do echo "i=$i"; done

This is hammer-to-crack-a-nut territory for this particular problem, but if you need to do something with a set of files with slightly complicated selection criteria, this can pay off quite quickly.

And it'd work in any sh-like shell.

Norman Gray
But it fails on filenames with control characters since `ls` tries to sanitize them.
Philipp
True, but if you have filenames with control characters in them, you probably have other problems (and not necessarily specifically technical ones)
Norman Gray
+1  A: 

you can use find as well...

find . -type f -not -iname "*.tar.gz"
ghostdog74