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
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
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 extended globbing operators are (excerpt from
If the extglob shell option is enabled using the shopt builtin, several extended pattern matching operators are recognized.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:
Matches zero or one occurrence of the given patterns
Matches zero or more occurrences of the given patterns
Matches one or more occurrences of the given patterns
Matches one of the given patterns
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
.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])