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

假设我想复制不包含名称中包含单词'Music'的文件和文件夹的目录的内容。

cp [exclude-matches] *Music* /target_directory

应该用什么来代替[排除匹配]来完成这个任务?


在Bash中,你可以通过启用extglob选项来实现,就像这样(当然,用cs代替ls并添加目标目录)

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

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

您可以使用shopt -s extglob打开它,然后使用shopt -u extglob将其关闭。

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

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

全部可用的扩展结束符glob操作符(摘自man bash ):

如果extglob shell选项使用shopt内建启用,则可以识别多个扩展模式匹配运算符。 在以下描述中,模式列表是由|分隔的一个或多个模式的列表。 复合图案可以使用一个或多个以下子图案形成:

  • ?(模式列表)
    匹配给定模式的零次或一次出现
  • *(模式列表)
    匹配零个或多个出现的给定模式
  • +(模式列表)
    匹配一个或多个出现的给定模式
  • @(模式列表)
    匹配一个给定的模式
  • !(模式列表)
    匹配除给定模式之外的任何内容
  • 因此,例如,如果您想列出当前目录中不是.c.h文件的所有文件,则可以这样做:

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

    当然,正常的外壳会起作用,所以最后一个例子也可以写成:

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

    不是bash(我知道),但是:

    cp `ls | grep -v Music` /target_directory
    

    我知道这不是你正在寻找的东西,但它会解决你的例子。

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

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

    下一篇: Python: Find in list