How can I use inverse or negative wildcards when p

2019-01-01 02:39发布

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?

11条回答
明月照影归
2楼-- · 2019-01-01 03:26

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.

查看更多
初与友歌
3楼-- · 2019-01-01 03:27

One solution for this can be found with find.

$ mkdir foo bar
$ touch foo/a.txt foo/Music.txt
$ find foo -type f ! -name '*Music*' -exec cp {} bar \;
$ ls bar
a.txt

Find has quite a few options, you can get pretty specific on what you include and exclude.

Edit: Adam in the comments noted that this is recursive. find options mindepth and maxdepth can be useful in controlling this.

查看更多
浮光初槿花落
4楼-- · 2019-01-01 03:28

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

~/foobar> shopt -s extglob
~/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
查看更多
柔情千种
5楼-- · 2019-01-01 03:29

In bash, an alternative to shopt -s extglob is the GLOBIGNORE variable. It's not really better, but I find it easier to remember.

An example that may be what the original poster wanted:

GLOBIGNORE="*techno*"; cp *Music* /only_good_music/

When done, unset GLOBIGNORE to be able to rm *techno* in the source directory.

查看更多
路过你的时光
6楼-- · 2019-01-01 03:31

You can also use a pretty simple for loop:

for f in `find . -not -name "*Music*"`
do
    cp $f /target/dir
done
查看更多
登录 后发表回答