How can I use inverse or negative wildcards when pattern matching in a unix/linux shell?

Say I want to copy the contents of a directory excluding files and folders whose names contain the word 'Music'.

cp [exclude-matches] *Music* /target_directory

What should go in place of [exclude-matches] to accomplish this?


In Bash you can do it by enabling the extglob option, like this (replace ls for cp and add the target directory, of course)

~/foobar> shopt extglob
extglob         off
~/foobar> ls
abar  afoo  bbar  bfoo
~/foobar> ls !(b*)
-bash: !: event not found
~/foobar> shopt -s extglob  #Enables extglob
~/foobar> ls !(b*)
abar  afoo
~/foobar> ls !(a*)
bbar  bfoo
~/foobar> ls !(*foo)
abar  bbar

You can later disable extglob with

shopt -u extglob

The extglob shell option gives you more powerful pattern matching in the command line.

You turn it on with shopt -s extglob , and turn it off with shopt -u extglob .

In your example, you would initially do:

$ shopt -s extglob
$ cp !(*Music*) /target_directory

The full available ext ended glob bing operators are (excerpt from man bash ):

If the extglob shell option is enabled using the shopt builtin, several extended pattern matching operators are recognized. In the following description, a pat tern-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, for example, if you wanted to list all the files in the current directory that are not .c or .h files, you would do:

    $ ls -d !(*@(.c|.h))
    

    Of course, normal shell globing works, so the last example could also be written as:

    $ ls -d !(*.[ch])
    

    Not in bash (that I know of), but:

    cp `ls | grep -v Music` /target_directory
    

    I know this is not exactly what you were looking for, but it will solve your example.

    链接地址: http://www.djcxy.com/p/47260.html

    上一篇: 扩展Git功能

    下一篇: 如何在unix / linux shell中进行模式匹配时使用反向或负向通配符?