8

In bash is it possible to use wildcards to specify "all files in current directory EXCEPT [files matching a specific (wildcard) pattern]"? Eg, "all files which don't match *~"

Or more generally, is it possible to qualify a wildcard file-spec with a second, filtering or negating specification?

2 Answers 2

8

Of course. Let's say you want all files the contain the string "foo" in their name, but none who also contain "bar". So you want

foo1
foo2

But you don't want

 foobar1

You can use simple globbing to do that like so:

for f in foo!(bar)*; echo $f; done

or so

ls foo[^bar]*

For more see here: http://www.tldp.org/LDP/abs/html/globbingref.html Beware, both methods have their pitfalls. You are probably better off using find.

2
  • Ah, I see - part of the extglob shopt. I don't usually have it enabled.
    – RashaMatt
    Jul 18, 2014 at 7:27
  • 5
    Note [^bar] does match a single character, all excluding b, a, and r.
    – Hannu
    Jul 18, 2014 at 16:15
4

Thanks bjanssen for pointing out bash's extglob shopt which allows this kind of globbing.

From the bash manpage:

If the extglob shell option is enabled using the shopt builtin, several
extended pattern matching operators are recognized. In the following 
description, a pattern-list is a list of one or more patterns separated 
by a |.  Composite patterns may be formed using one or more of the following
sub-patterns:

          ?(pattern-list)
                 Matches zero or one occurrence of the given patterns
          *(pattern-list)
                 Matches zero or more occurrences of the given patterns
          +(pattern-list)
                 Matches one or more occurrences of the given patterns
          @(pattern-list)
                 Matches one of the given patterns
          !(pattern-list)
                 Matches anything except one of the given patterns

So, to answer my question "how to specify all files which don't match *~" :

!(*~)

or, without the need for extglob:

*[^~]

And more generally, answering the last part of my question:

The GLOBIGNORE shell variable may be used to restrict the set of file names
matching a pattern. If GLOBIGNORE is set, each matching file name that also
matches one of the (colon-separated) patterns in GLOBIGNORE is removed from
the list of matches.
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .