假设我有一个包含文件 a1、a2、a3、b1、b2、b3 的目录。我只想匹配以 开头a
但不包含3
.我尝试过,ls -I "*3" *a*
但它返回了a1 a2 a3
,尽管我不希望它匹配a3
。这可能吗ls
?
答案1
只是:
shopt -s extglob failglob
ls -d a!(*3*)
shopt -s extglob
激活扩展通配符(启用 ksh 扩展运算符的子集)。failglob
如果没有匹配项,它会取消命令,而不是按原样保留全局模式来调用它。如果没有它,最终可能会列出所调用的文件,a!(*3*)
即使它包含3
.a
匹配起始a
!()
()
否定...内的匹配*3*
这是3
以及它之前或之后的任何内容。
$ touch 1 2 3 a1 a2 a3 b1 b2 b3 aa1 aa2 aa3 a2a a3a
$ ls -d a!(*3*)
a1 a2 a2a aa1 aa2
答案2
现有的答案很好地说明了使用 glob 实现此目的的最佳方法;我将包含此内容,因为在大多数情况下,find
如果您想进行脚本编写或进一步处理,这是一个更好的选择:
$ find . -maxdepth 1 -name 'a*' -not -name '*3*'
./a1
./a2
您可以将答案提供xargs
给简单的操作,或者将答案提供给while read
循环来处理更复杂的事情。
答案3
一个简单的方法是
- 列出所有匹配的文件
a*
- 然后删除所有包含a的行
3
UNIX 命令是
ls -1 a* | grep -v 3
ls -1
每行显示一个文件。
grep
通常查找与模式匹配的行,但-v
这种行为是相反的,即 grep 查找与该模式不匹配的行。
答案4
正如之前的答案所建议的:是的,可以用以下方法解决这个问题LS。对我来说,这个特殊的问题也在某种程度上暗示了为什么你的解决方案没有奏效。因此,我想对此做出迟来的贡献。
基本上,
ls -I "*3" *a*
要求排除所有以以下结尾的条目3,但又包括明确地所有包含A。实际上,*A*使用 shell 通配符并进行扩展前实际命令被执行(这不适用于“*3”正如这部分所引用的那样)。因此,您的命令在您的情况下相当于
ls -I "*3" a1 a2 a3
因此列出该条目a3。因此,要列出的明确给定条目是与以下相关的否决条目-我。从那里我得出,隐含地从手册的意义上来说一切未明确指定的内容,例如
ls -I "*3"
会排除a3(但也显示了该目录中其他考虑的条目,例如b1)。