You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash extglob反向模式匹配内部原理及异常命令解析

Bash扩展通配符(extglob)解析逻辑说明

当前目录文件列表

-rw-r--r-- 1 kazama kazama 0 Feb 16 08:50 london_july_2001_001.jpeg
-rw-r--r-- 1 kazama kazama 0 Feb 16 08:50 london_march_2004_002.png
-rw-r--r-- 1 kazama kazama 0 Feb 16 08:50 newyork_dec_2012_005.jpeg
-rw-r--r-- 1 kazama kazama 0 Feb 16 08:50 paris_sept_2007_003.jpg

需求与问题

需求是过滤掉所有以paris开头的图片文件。使用ls -l !(paris*)能得到预期结果,但ls -l !(paris)*.*(jpeg|jpg|png)和ls -l !(paris)*这两个命令却会显示全部4个文件,核心疑问是Bash如何解析这些extglob语法,是否分段匹配。

解析逻辑

Bash的扩展通配符(extglob)是以整个模式为单位匹配文件名,而非拆分后分段执行匹配,具体拆解如下:

  1. !(paris*)的正确匹配
    这个模式的含义是「匹配任何不以paris开头的文件名」,paris*作为一个整体被排除,因此能精准过滤掉所有paris开头的文件,符合预期。

  2. !(paris)*的问题所在
    !(paris)的含义是「匹配任何不等于精确字符串paris的内容」——它可以匹配空字符串、parisx这类包含paris但不全等于paris的字符串,甚至任意长度的非paris字符串。
    当匹配paris_sept_2007_003.jpg时,Bash会将文件名拆分为「空字符串」(匹配!(paris),因为空字符串≠paris)和「整个文件名内容」(匹配后面的*),因此整个模式匹配成功,导致该文件被错误包含。

  3. !(paris)*.*(jpeg|jpg|png)的问题同理
    同样的逻辑,!(paris)可以匹配空字符串,后续的*.*(jpeg|jpg|png)会匹配整个文件名,最终paris开头的图片文件也会被匹配到。

正确的写法

如果要实现「过滤掉paris开头的图片文件」,正确的extglob模式应该是:

ls -l !(paris*).*(jpeg|jpg|png)

这里!(paris*)作为整体排除所有paris开头的文件,再通过.*(jpeg|jpg|png)限定图片后缀,就能得到符合需求的结果。

内容的提问来源于stack exchange,提问作者Sking

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 00:50:23