Bash 在unix/linux shell中进行模式匹配时,如何使用反向或负通配符?
假设我要复制目录的内容,但不包括名称中包含单词“Music”的文件和文件夹Bash 在unix/linux shell中进行模式匹配时,如何使用反向或负通配符?,bash,shell,pattern-matching,glob,Bash,Shell,Pattern Matching,Glob,假设我要复制目录的内容,但不包括名称中包含单词“Music”的文件和文件夹 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有
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中(据我所知),而是:
我知道这并不完全是您想要的,但它将解决您的示例。不是在bash中(我知道),而是:
我知道这并不完全是您想要的,但它将解决您的示例。您也可以使用非常简单的
for
循环:
for f in `find . -not -name "*Music*"`
do
cp $f /target/dir
done
您还可以使用非常简单的
for
循环:
for f in `find . -not -name "*Music*"`
do
cp $f /target/dir
done
在Bash中,您可以通过如下方式启用
extglob
选项来实现这一点(当然,将ls
替换为cp
并添加目标目录)
您可以稍后使用禁用extglob
shopt -u extglob
在Bash中,您可以通过如下方式启用
extglob
选项来实现这一点(当然,将ls
替换为cp
并添加目标目录)
您可以稍后使用禁用extglob
shopt -u extglob
如果您想避免使用exec命令的mem成本,我相信您可以使用xargs做得更好。我认为以下是一个更有效的替代方案
find foo -type f ! -name '*Music*' -exec cp {} bar \; # new proc for each exec
find . -maxdepth 1 -name '*Music*' -prune -o -print0 | xargs -0 -i cp {} dest/
如果您想避免使用exec命令的mem成本,我相信您可以使用xargs做得更好。我认为以下是一个更有效的替代方案
find foo -type f ! -name '*Music*' -exec cp {} bar \; # new proc for each exec
find . -maxdepth 1 -name '*Music*' -prune -o -print0 | xargs -0 -i cp {} dest/
extglob
shell选项在命令行中提供了更强大的模式匹配功能
您可以使用shopt-s extglob
打开它,然后使用shopt-u extglob
关闭它
在您的示例中,您最初会执行以下操作:
$ shopt -s extglob
$ cp !(*Music*) /target_directory
完整可用的ext结束的globbing操作符是(摘自manbash
):
如果使用shopt内置函数启用extglob shell选项,则会有几个扩展
识别模式匹配运算符。模式列表是由一个或多个模式组成的列表,这些模式由|分隔。组合模式可以使用以下一个或多个子模式形成:
- ?(模式列表)
匹配给定模式的零个或一个匹配项 - *(图案列表)
匹配给定模式的零次或多次出现 - +(图案列表)
匹配给定模式的一个或多个匹配项 - @(图案列表)
匹配给定模式之一 - !!(图案列表)
匹配除一个给定模式之外的任何模式
.c
或.h
文件的所有文件,您可以执行以下操作:
$ ls -d !(*@(.c|.h))
当然,正常的外壳全球化是有效的,因此最后一个示例也可以写成:
$ ls -d !(*.[ch])
extglob
shell选项在命令行中提供了更强大的模式匹配功能
您可以使用shopt-s extglob
打开它,然后使用shopt-u extglob
关闭它
在您的示例中,您最初会执行以下操作:
$ shopt -s extglob
$ cp !(*Music*) /target_directory
完整可用的ext结束的globbing操作符是(摘自manbash
):
如果使用shopt内置函数启用extglob shell选项,则会有几个扩展
识别模式匹配运算符。模式列表是由一个或多个模式组成的列表,这些模式由|分隔。组合模式可以使用以下一个或多个子模式形成:
- ?(模式列表)
匹配给定模式的零个或一个匹配项 - *(图案列表)
匹配给定模式的零次或多次出现 - +(图案列表)
匹配给定模式的一个或多个匹配项 - @(图案列表)
匹配给定模式之一 - !!(图案列表)
匹配除一个给定模式之外的任何模式
.c
或.h
文件的所有文件,您可以执行以下操作:
$ ls -d !(*@(.c|.h))
当然,正常的外壳全球化是有效的,因此最后一个示例也可以写成:
$ ls -d !(*.[ch])
这样就可以完全排除“音乐”
cp -a ^'Music' /target
这个和那个用来排除音乐之类的东西
cp -a ^\*?'complete' /target
cp -a ^'complete'?\* /target
这样就可以完全排除“音乐”
cp -a ^'Music' /target
这个和那个用来排除音乐之类的东西
cp -a ^\*?'complete' /target
cp -a ^'complete'?\* /target
我个人的偏好是使用grep和while命令。这使我们能够编写强大但可读的脚本,确保您最终完全按照自己的意愿完成任务。另外,通过使用echo命令,您可以在执行实际操作之前执行试运行。例如:
ls | grep -v "Music" | while read filename
do
echo $filename
done
将打印出最终要复制的文件。如果列表正确,下一步就是用copy命令替换echo命令,如下所示:
ls | grep -v "Music" | while read filename
do
cp "$filename" /target_directory
done
我个人的偏好是使用grep和while命令。这使我们能够编写强大但可读的脚本,确保您最终完全按照自己的意愿完成任务。另外,通过使用echo命令,您可以在执行实际操作之前执行试运行。例如:
ls | grep -v "Music" | while read filename
do
echo $filename
done
将打印出最终要复制的文件。如果列表正确,下一步就是用copy命令替换echo命令,如下所示:
ls | grep -v "Music" | while read filename
do
cp "$filename" /target_directory
done
以下作品列出了当前目录中的所有
*.txt
文件,除了