当前位置: 首页 > article >正文

探索 Shell 中的扩展通配符:从 Bash 到 Zsh

在 Unix 系统中,通配符(globbing)是 shell 的核心功能,用于快速匹配文件或目录。基础通配符(如 *?[])虽简单实用,但在复杂场景下往往力不从心。为此,许多现代 shell 提供了“扩展通配符”功能,通过特定选项(如 Bash 的 shopt -s extglob 或 Zsh 的 setopt extendedglob)解锁更强大的匹配能力。这些扩展通配符不仅增强了灵活性,还引入了类似正则表达式的语法,使文件操作更加高效。本文将详细介绍 Bash 和 Zsh 的扩展通配符特性,区分其功能与应用场景,并探讨其实际价值,帮助读者全面掌握这一高级工具。


一、扩展通配符的背景与意义

基础通配符在 Unix 系统中由来已久,但其功能局限于简单匹配,无法满足复杂需求,例如否定匹配、递归查找或多条件过滤。为弥补这一不足,现代 shell 引入了扩展通配符,通过额外的配置选项提供更丰富的模式匹配能力。Bash 的 extglob 和 Zsh 的 extendedglob 是其中的佼佼者,它们不仅扩展了通配符的表达能力,还为用户提供了近乎正则表达式级别的控制力。

扩展通配符的意义在于,它将 shell 从简单的命令执行工具提升为强大的文件处理平台。无论是批量操作、日志筛选还是项目管理,这些功能都能显著提升效率。


二、主流 Shell 的扩展通配符详解

1. Bash 的扩展通配符(extglob

Bash 的扩展通配符需通过 shopt -s extglob 启用,提供比基础通配符更强大的匹配能力。

1.1 启用方法
  • 临时启用
    shopt -s extglob
    
  • 永久启用
    echo "shopt -s extglob" >> ~/.bashrc
    source ~/.bashrc
    
1.2 核心语法与功能
  • !(pattern):否定匹配,匹配不符合 pattern 的内容。
  • *(pattern):匹配零次或多次。
  • +(pattern):匹配一次或多次。
  • @(pattern):匹配恰好一次。
  • ?(pattern):匹配零次或一次。
  • 示例
    • ls !(*.txt):列出非 .txt 文件。
    • ls *(a|b):匹配含零次或多次 ab 的文件。
    • ls +(v[0-9]):匹配含一次或多次版本号(如 v1v2)的文件。
    • ls @(test|prod).conf:匹配 test.confprod.conf
    • ls ?(file|dir):匹配 filedir 或空字符串。
1.3 特点与局限
  • 特点:语法直观,适合中等复杂度的匹配任务。
  • 局限
    • 不支持原生递归匹配(需另启用 shopt -s globstar 使用 **)。
    • 语法较繁琐,嵌套能力有限。
    • 无法直接组合多个条件(如排除多类文件需嵌套多个模式)。
1.4 递归扩展(配合 globstar
  • 启用shopt -s globstar
  • 语法**/*.ext
  • 示例ls **/*.sh(递归匹配 .sh 文件)。
  • 说明globstar 是独立选项,与 extglob 可组合使用,但功能仍不及 Zsh。

2. Zsh 的扩展通配符(extendedglob

Zsh 的扩展通配符通过 setopt extendedglob 启用,功能远超 Bash,提供更灵活和强大的匹配能力。

2.1 启用方法
  • 临时启用
    setopt extendedglob
    
  • 永久启用
    echo "setopt extendedglob" >> ~/.zshrc
    source ~/.zshrc
    
2.2 核心语法与功能
  • ^pattern:否定匹配,匹配不符合 pattern 的内容。
  • pattern1~pattern2:匹配符合 pattern1 但不符合 pattern2 的内容。
  • (pattern1|pattern2):分组匹配,匹配任一模式。
  • pattern#:匹配零次或多次。
  • pattern##:匹配一次或多次。
  • **/*.ext:递归匹配子目录(默认支持,无需额外选项)。
  • (#X):修饰符,如 (#i)(忽略大小写)、(#l)(仅小写)。
  • 示例
    • ls ^*.txt:列出非 .txt 文件。
    • ls *.txt~*.old.txt:匹配 .txt 文件,排除 .old.txt
    • ls *(txt|log):匹配 .txt.log 文件。
    • ls *#v[0-9]*.log:匹配含零次或多次版本号的 .log 文件。
    • ls **/*.sh:递归匹配所有 .sh 文件。
    • ls *test*(#i):匹配含 test 的文件,忽略大小写。
2.3 特点与优势
  • 特点
    • 语法简洁直观,操作符(如 ^~)易于理解。
    • 默认支持递归匹配(**),无需额外配置。
    • 支持复杂逻辑组合(如多重排除、分组)。
  • 优势
    • 比 Bash 的 extglob 更强大,接近正则表达式。
    • 与 Zsh 其他特性(如限定符 (#q))无缝集成。

3. 其他 Shell 的扩展通配符(简述)

  • Ksh(Korn Shell)
    • 支持类似 Bash 的扩展通配符(如 !(pattern)),语法与 Bash extglob 接近。
    • 示例:ls !(*.bak)
    • 特点:功能较 Bash 略强,但普及度较低。
  • Fish Shell
    • 不依赖传统扩展通配符,注重简洁性。
    • 使用 ** 递归匹配,但无复杂模式支持。
    • 示例:ls **/*.txt
    • 特点:用户友好,但高级功能有限。

三、Bash 与 Zsh 扩展通配符的对比

特性Bash (extglob)Zsh (extendedglob)
启用方式shopt -s extglobsetopt extendedglob
否定匹配!(pattern)^pattern
排除匹配无直接支持,需嵌套 !(...)pattern1~pattern2
分组匹配@(pattern1|pattern2)(pattern1|pattern2)
重复匹配*(pattern)+(pattern)pattern#pattern##
递归匹配shopt -s globstar 使用 **默认支持 *****
修饰符支持 (#i)
语法简洁性较繁琐更直观简洁
复杂逻辑支持有限强大(如多重排除、嵌套)

结论:Bash 的 extglob 适合中等复杂度的任务,但语法繁琐且功能有限;Zsh 的 extendedglob 则更强大、灵活,特别在递归匹配和复杂逻辑上占据优势。


四、扩展通配符的实际应用场景

1. 文件清理

  • Bashrm !(*.bak|*.tar.gz)(删除除 .bak.tar.gz 外的文件)。
  • Zshrm *~(*.bak|*.tar.gz)(更简洁的排除语法)。

2. 递归查找

  • Bashls **/*.sh(需启用 globstar)。
  • Zshls **/*.sh~*.old.sh(递归匹配非 .old.sh.sh 文件)。

3. 批量重命名

  • Bash
    for f in !(*.old.txt); do mv "$f" "${f%.txt}.new"; done
    
  • Zsh
    for f in *.txt~*.old.txt; do mv $f ${f%.txt}.new; done
    

4. 日志筛选

  • Bashls +(v[0-9]).log(匹配含版本号的日志)。
  • Zshls *#v[0-9]#*.log(更灵活的版本号匹配)。

5. 忽略大小写

  • Bash:无直接支持,需借助 tr 或其他工具。
  • Zshls *test*(#i)(忽略大小写匹配)。

五、使用扩展通配符的注意事项

  1. 兼容性

    • Bash:启用 extglob 后不影响基础通配符。
    • Zsh:^~ 等符号含义改变,可能影响现有脚本。
    • 解决:脚本中明确控制选项(如 setopt noextendedglob)。
  2. 性能

    • 递归匹配(如 **)在大型目录中可能较慢。
    • 解决:缩小范围或结合 find
  3. 调试

    • echo 测试匹配结果,如 echo !(*.txt)echo ^*.txt
  4. 与其他选项的交互

    • Bash:extglobglobstar 可组合。
    • Zsh:extendedglobglobstar 等选项需一致配置。

六、总结

扩展通配符是 shell 功能的重要进化,Bash 的 extglob 提供了实用的增强,而 Zsh 的 extendedglob 则将这一能力推向巅峰。从否定匹配到递归查找,从分组到修饰符,Zsh 的扩展通配符以其简洁性和强大性脱颖而出。无论您是 Bash 用户还是 Zsh 爱好者,掌握这些工具都能让命令行操作更加得心应手。不妨现在尝试启用 shopt -s extglobsetopt extendedglob,体验扩展通配符的魅力!

相关文章:

探索 Shell 中的扩展通配符:从 Bash 到 Zsh

在 Unix 系统中,通配符(globbing)是 shell 的核心功能,用于快速匹配文件或目录。基础通配符(如 *、?、[])虽简单实用,但在复杂场景下往往力不从心。为此,许多现代 shell 提供了“扩…...

封装方法的辨析

equals //字符串 str1.equals(str2); //list的两个实现类 list1.equals(list2); //map的两个实现类 //比较所有的键值对是否相同 map1.equals(map2); //数组(包括string类型) //比较内容是否相同 Arrays.equals(array1, array2); contains 基本都有…...

[leetcode]判断质数

一.判断质数 1.1 什么是质数 质数&#xff08;素数&#xff09;就是只可以被自己和1整除的数叫做素数/质数 1.2判断方法 #include<bits/stdc.h> using namespace std; bool isPrime(int num) { if(num < 1) { return false;//a number less of …...

在Flutter中使用BottomNavigationBar和IndexedStack可以实现一个功能完整的底部导航栏

在Flutter中&#xff0c;使用BottomNavigationBar和IndexedStack可以实现一个功能完整的底部导航栏。BottomNavigationBar用于显示底部的导航按钮&#xff0c;而IndexedStack则用于管理页面的切换&#xff0c;确保每个页面的状态得以保留&#xff08;即页面不会因为切换而重新构…...

HBuilder运行uni-app程序报错【Error: listen EACCES: permission denied 0.0.0.0:5173】

一、错误提示&#xff1a; 当使用HBuilder运行uni-app项目的时候提示了如下错误❌ 15:11:03.089 项目 project 开始编译 15:11:04.404 请注意运行模式下&#xff0c;因日志输出、sourcemap 以及未压缩源码等原因&#xff0c;性能和包体积&#xff0c;均不及发行模式。 15:11:04…...

聊透多线程编程-线程基础-3.C# Thread 如何从非UI线程直接更新UI元素

目录 1. 使用 Control.Invoke 或 Control.BeginInvoke&#xff08;Windows Forms&#xff09; 2. 使用 Dispatcher.Invoke 或 Dispatcher.BeginInvoke&#xff08;WPF&#xff09; 3. 使用 SynchronizationContext 桌面应用程序&#xff08;如 Windows Forms 或 WPF&#xf…...

VMware Fusion Pro 13 for Mac虚拟机

VMware Fusion Pro 13 for Mac虚拟机 文章目录 VMware Fusion Pro 13 for Mac虚拟机一、介绍二、效果下载 一、介绍 VMware Fusion Pro for Mac&#xff0c;是一款mac虚拟机软件&#xff0c;跟Parallels Desktop一样&#xff0c;都可以让你的 Mac 同时运行一个或多个不同的操作…...

7.第二阶段x64游戏实战-string类

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;7.第二阶段x64游戏实战-分析人物属性 string类是字符串类&#xff0c;在计算机中…...

【debug莫名其妙跑飞了】

现象&#xff1a;就是在初始化汇编里跑飞了&#xff0c;也可能运行起来时钟不对 原因&#xff1a;调试器调试程序时会执行reset复位&#xff0c;reset没有正确执行。 细节决定成败&#xff0c;事出反常必有妖&#xff0c;忽略的小卡拉米最后能玩死你啊...

【Git 常用操作指令指南】

一、初始化与配置 1. 设置全局账户信息 git config --global user.name "用户名" # 设置全局用户名 git config --global user.email "邮箱" # 设置全局邮箱 --global 表示全局生效&#xff0c;若需针对单个仓库配置&#xff0c;可省略该参数 2.…...

基础知识补充篇:什么是DAPP前端连接中的provider

专栏:区块链入门到放弃查看目录-CSDN博客文章浏览阅读352次。为了方便查看将本专栏的所有内容列出目录,按照顺序查看即可。后续也会在此规划一下后续内容,因此如果遇到不能点击的,代表还没有更新。声明:文中所出观点大多数源于笔者多年开发经验所总结,如果你想要知道区块…...

openssl源码分析之加密模式(modes)

openssl实现分组加密模式&#xff08;例如AES128-CBC的CBC部分&#xff09;的模块名字叫做modes&#xff0c;源代码位于 https://gitee.com/gh_mirrors/openssl/tree/master/crypto/modes 博主又打不开github了TT&#xff0c;只能找个gitee镜像 头文件是modes.h。 该模块目前…...

【PVR】《Palm Vein Recognition and Large-scale Research based on Deep Learning》

邬晓毅. 基于深度学习的掌静脉识别及规模化研究[D]. 四川:电子科技大学,2024. 文章目录 1、背景2、相关工作3、创新点和贡献4、方法和实验4.1、知识介绍4.2、基于自适应损失函数的掌静脉识别算法研究4.3、退化图像的掌静脉识别鲁棒性提升研究4.4、掌静脉识别系统规模化 5、总结…...

ES6规范新特性总结

ES6新特性 var、let和const不存在变量提升暂时性死区不允许重复声明 解构赋值用途&#xff1a;交换变量的值从函数返回多个值提取JSON数据遍历map结构输入模块的制定方法 字符串的扩展codePointAt()String.fromCharCode()at()includes(),startsWith(),endsWith()repeat()padSta…...

PyQt学习记录

PyQt学习记录 要在界面上 创建一个控件&#xff0c;就需要在程序代码中 创建 这个 控件对应类 地一个 实例对象。 在Qt系统中&#xff0c;控件&#xff08;widget&#xff09;是 层层嵌套 的&#xff0c;除了最顶层的控件&#xff0c;其他的控件都有父控件。 几个函数 函数mo…...

嵌入式硬件篇---Uart和Zigbee

文章目录 前言一、UART&#xff08;通用异步收发传输器&#xff09;1. 基本概念2. 工作原理帧结构起始位数据位校验位停止位 异步通信波特率 3. 特点优点缺点 4. 典型应用 二、ZigBee1. 基本概念2. 技术细节工作频段2.4GHz868MHz 网络拓扑星型网络网状网络簇状网络 协议栈物理层…...

代码随想录算法训练营--打卡day8

一.反转字符串II 1.题目链接 541. 反转字符串 II - 力扣&#xff08;LeetCode&#xff09; 2.思路 循环分组定位&#xff1a;使用 for 循环&#xff0c;每2k为一组。i 每次增加 2k &#xff0c;就相当于定位到下一组字符的起始位置。在每次循环中&#xff0c;确定当前组需要…...

Linux 学习笔记(5)路径知识详解:绝对路径、相对路径与特殊路径符(期末、期中复习必备)

前言 一、相对路径与绝对路径 1、概念阐述 2、实际示例 二、特殊路径符 1.特殊路径符介绍 2.应用场景 三、总结 四、结语 前言 在 Linux 系统的学习过程中&#xff0c;路径的概念至关重要&#xff0c;它是我们在文件系统中定位文件和目录的关键。今天&#xff0c;我们就…...

Trae + LangGPT 生成结构化 Prompt

Trae LangGPT 生成结构化 Prompt 0. 引言1. 安装 Trae2. 克隆 LangGPT3. Trae 和 LangGPT 联动4. 集成到 Dify 中 0. 引言 Github 上 LangGPT 这个项目&#xff0c;主要向我们介绍了写结构化Prompt的一些方法和示例&#xff0c;我们怎么直接使用这个项目&#xff0c;辅助我们…...

【ida】ida笔记

1 ida下载 IDA Pro 7.0 Windows 和 macOS 版本&#xff0c;包含全部 F5 插件 - 资源分享 - iOS 安全论坛 - 专注于研究 iOS 安全 - iOS Hacker 2 IDA基操 1 shiftF12 查看string信息 (通常可以看到重要的信息 ) 2 Alt T 查找带有目标字符串的函数 3 F5 查看C代码 4 Ctrl F…...

动态规划——两个数组的dp问题

目录 1. 最长公共子序列 2. 不相交的线 3. 不同的子序列 4. 通配符匹配 5. 正则表达式匹配 6. 交错字符串 7. 两个字符串的最小ASCII删除和 8. 最长重复子数组 1. 最长公共子序列 题目链接&#xff1a;1143. 最长公共子序列 - 力扣&#xff08;LeetCode&#xff0…...

stream流Collectors.toMap(),key值重复问题

文章目录 一、问题二、问题示例三、原因四、解决方法4.1、方案一 一、问题 发现Collectors.toMap的一个坑&#xff0c;若key值重复的时候会抛异常。如&#xff1a; IllegalStateException: Duplicate key 男 二、问题示例 报错示例如下&#xff1a; import lombok.AllArgsC…...

机器学习 Day10 逻辑回归

1.简介 流程就是&#xff1a; 就是我们希望回归后激活函数给出的概率越是1和0. 2.API介绍 sklearn.linear_model.LogisticRegression 是 scikit-learn 库中用于实现逻辑回归算法的类&#xff0c;主要用于二分类或多分类问题。以下是对其重要参数的详细介绍&#xff1a; 2.1.…...

即时通讯软件BeeWorks,企业如何实现细粒度的权限控制?

BeeWorks作为一款专为企业设计的即时通讯平台&#xff0c;高度重视用户隐私安全&#xff0c;采取了多种措施来保障数据的保密性、完整性和可用性。 首先&#xff0c;BeeWorks采用私有化部署模式&#xff0c;企业可以将服务器架设在自己的网络环境中&#xff0c;所有通讯数据&a…...

Seq2Seq - Dataset 类

本节代码定义了一个 CMN 类&#xff0c;它继承自 PyTorch 的 Dataset 类&#xff0c;用于处理英文和中文的平行语料库。这个类的主要作用是将文本数据转换为模型可以处理的格式&#xff0c;并进行必要的填充操作&#xff0c;以确保所有序列的长度一致。 ⭐重写Dataset类是模型训…...

学习OpenCV C++版

OpenCV C 1 数据载入、显示与保存1.1 概念1.2 Mat 类构造与赋值1.3 Mat 类的赋值1.4 Mat 类支持的运算1.5 图像的读取与显示1.6 视频加载与摄像头调用1.7 数据保存 参考&#xff1a;《OpenCV4快速入门》作者冯 振 郭延宁 吕跃勇 1 数据载入、显示与保存 1.1 概念 Mat 类 : Ma…...

echarts图表相关

echarts图表相关 echarts官网折线图实际开发场景一&#xff1a; echarts官网 echarts官网 折线图 实际开发场景一&#xff1a; 只有一条折线&#xff0c;一半实线&#xff0c;一半虚线。 option {tooltip: {trigger: "axis",formatter: (params: any) > {const …...

idea自动部署jar包到服务器Alibaba Cloud Toolkit

安装插件&#xff1a;Alibaba Cloud Toolkit 配置服务器: 服务器配置&#xff1a; 项目启动Shell脚本命令: projectpd-otb.jar echo 根据项目名称查询对应的pid pid$(pgrep -f $project); echo $pid echo 杀掉对应的进程&#xff0c;如果pid不存在&#xff0c;则不执行 if [ …...

奥利司他

https://m.baidu.com/bh/m/detail/ar_9900965142893895938 奥利司他&#xff08;四氢脂抑素&#xff09;是一种众所周知的胰腺和胃脂肪酶不可逆抑制剂 生物活性&#xff1a;奥利司他&#xff08;四氢脂抑素&#xff09;是一种众所周知的胰腺和胃脂肪酶不可逆抑制剂。奥利司…...

Element Plus 图标使用方式整理

Element Plus 图标使用方式整理 以下是 Element Plus 图标的所有使用方式&#xff0c;包含完整代码示例和总结表格&#xff1a; 1. 按需引入图标组件 适用场景&#xff1a;仅需少量图标时&#xff0c;按需导入减少打包体积 示例代码&#xff1a; <template><div>…...