假设我想复制一个目录的内容,不包括名称包含单词“音乐”的文件和文件夹。

cp [exclude-matches] *Music* /target_directory

应该用什么来代替[排除匹配]来实现这一点?


当前回答

这样就可以排除“音乐”

cp -a ^'Music' /target

排除音乐之类的东西?*还是*?音乐

cp -a ^\*?'complete' /target
cp -a ^'complete'?\* /target

其他回答

在Bash中,您可以通过启用extglob选项来做到这一点,就像这样(当然,将ls替换为cp并添加目标目录)

~/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

您可以稍后禁用extglob

shopt -u extglob

不是bash(据我所知),而是:

cp `ls | grep -v Music` /target_directory

我知道这不是你想要的,但它能解决你的问题。

这样就可以排除“音乐”

cp -a ^'Music' /target

排除音乐之类的东西?*还是*?音乐

cp -a ^\*?'complete' /target
cp -a ^'complete'?\* /target

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有相当多的选项,你可以非常具体地包括和排除什么。

编辑:Adam在评论中指出,这是递归的。查找选项mindepth和maxdepth可以用来控制这个。

在bash中,shopt -s extglob的替代方法是GLOBIGNORE变量。它并不是更好,但我发现它更容易记住。

下面的例子可能就是最初的海报想要的:

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

完成后,取消设置GLOBIGNORE,以便能够在源目录中rm *techno*。