从全局匹配中排除模式

从全局匹配中排除模式

我的目录如下所示:

$ ls
total 0
-rw-r--r-- 1 user user 0 Jun 18 22:44 file0
-rw-r--r-- 1 user user 0 Jun 18 22:44 file1
-rw-r--r-- 1 user user 0 Jun 18 22:44 file2
-rw-r--r-- 1 user user 0 Jun 18 22:44 file3
-rw-r--r-- 1 user user 0 Jun 18 22:44 file4
-rw-r--r-- 1 user user 0 Jun 18 22:44 file5
-rw-r--r-- 1 user user 0 Jun 18 22:44 file6
-rw-r--r-- 1 user user 0 Jun 18 22:44 file7
-rw-r--r-- 1 user user 0 Jun 18 22:44 file8
-rw-r--r-- 1 user user 0 Jun 18 22:44 file9

使用 bash 通配符,我想file2匹配file6排除 file3

由于我找不到and匹配多个模式的运算符,我想我只是使用德摩根定律,它a AND b相当于!(!a OR !b)并写

!(!(file[2-6])|file3)

其按预期工作:

$ echo !(!(file[2-6])|file3)
file2 file4 file5 file6

有没有更简单、更直接的方法来实现这一目标?

答案1

您可以应用两个 range [24-6],其中2是第一个,4-6是第二个:

$ ls file[24-6]
file2 file4 file5 file6

另一个例子:

$ ls file[2356]
file2 file3 file5 file6

文档:

范围

有一个特殊约定:用“-”分隔的两个字符表示一个范围。 (因此,“[A-Fa-f0-9]”相当于“[ABCDEFabcdef0123456789]”。)可以通过将“-”作为括号之间的第一个或最后一个字符来包含其字面含义。 (因此,“[]-]”仅匹配两个字符“]”和“-”,“[--0]”匹配三个字符“-”、“.”、“0”,因为“/”无法匹配。)

答案2

取反范围:

printf '%s\n' file[!013789]

如此处所述:

如果“[”后面的第一个字符是“!”或 '^' 则匹配任何未包含的字符。


设置GLOBIGNORE为您要跳过的文件:

GLOBIGNORE="file0:file1:file3:file7:file8:file9"
printf '%s\n' file*

看到这个:

GLOBIGNORE shell 变量可用于限制与模式匹配的文件名集。如果设置了 GLOBIGNORE,则将从匹配列表中删除也与 GLOBIGNORE 中的模式之一匹配的每个匹配文件名。


使用extended globbing

shopt -s extglob
printf '%s\n' file!([013789])

请参阅扩展通配符

相关内容