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

cp [exclude-matches] *Music* /target_directory

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


当前回答

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可以用来控制这个。

其他回答

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(据我所知),而是:

cp `ls | grep -v Music` /target_directory

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

这样就可以排除“音乐”

cp -a ^'Music' /target

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

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

extglob shell选项在命令行中为您提供了更强大的模式匹配。

用shopt -s extglob打开它,用shopt -u extglob关闭它。

在你的例子中,你最初会做:

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

完全可用的扩展通配符是(摘自man bash):

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: ?(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

因此,例如,如果你想列出当前目录中所有不是。c或。h文件的文件,你会这样做:

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

当然,普通的shell globing也可以,所以最后一个例子也可以写成:

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

你也可以使用一个非常简单的for循环:

for f in `find . -not -name "*Music*"`
do
    cp $f /target/dir
done