列出与某个模式匹配的文件,但忽略与另一个模式匹配的文件?


12

假设我有一个目录,其中包含文件a1,a2,a3,b1,b2,b3。我只想匹配以开头a但不包含的文件3。我尝试了ls -I "*3" *a*但它返回了a1 a2 a3,即使我不希望它匹配a3。这可能ls吗?


有趣的各种答案在这里,但是对ls -I'* 3'a *失败的原因的解释很有根据。和/或为什么后来忽略忽略切换到ls后,shell的全局列表没有被过滤?
Theophrastus 2015年

手册页介绍了-I选项:do not list implied entries matching shell PATTERN,但是它没有解释隐含的含义,但是我猜测它仅适用于ls通过glob扩展获取的文件,而ls不会扩展a*-shell会执行此操作。
Murray Jensen

Answers:


14

只是:

shopt -s extglob  
ls a!(*3*)
  • shopt -s extglob 激活扩展的globbing。
  • a 匹配开始 a
  • !()取消比赛中的比赛()...
    • *3*这是3和任何东西之前或之后。

$ touch 1 2 3 a1 a2 a3 b1 b2 b3 aa1 aa2 aa3 a2a a3a
$ ls a!(*3*)
a1  a2  a2a  aa1  aa2

1
仅供参考,要求set -s extglob
Brian

@Brian Yea,刚注意到^^
混乱

8

现有的答案很好地说明了解决问题的最佳方法。我将其包括在内,因为在大多数情况下,find如果要进行脚本编写或进一步处理,这是一个更好的选择:

$ find . -maxdepth 1 -name 'a*' -not -name '*3*'
./a1
./a2

您可以输入答案以xargs执行简单的操作,也可以输入while read循环以执行更复杂的操作。


4

一个简单的方法是

  • 列出所有匹配的文件 a*
  • 然后删除所有包含 3

UNIX命令是

ls -1 a* | grep -v 3

ls -1 每行显示一个文件。

grep通常会找到与某个模式匹配的行,但是-v这种行为是相反的,即grep找到与该模式不匹配的行。


2
嗨,彼得!最好尽可能详细地说明解决方案的工作原理。
dhag 2015年

2
解析ls不是一个愚蠢的主意:mywiki.wooledge.org/ParsingLs
混乱

3

使用zsh,使用~ glob运算符

setopt extendedglob
print -rl -- a*~*3*

有了gnu ls您可以使用两个--ignore选项:

ls -I '[^a]*' -I '*3*'

第一个忽略所有不以开头的a文件名,第二个忽略包含3

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.