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

Shell 中的 Globbing:原理、使用方法与实现解析(中英双语)

Shell 中的 Globbing:原理、使用方法与实现解析

在 Unix Shell(如 Bash、Zsh)中,globbing 是指 文件名模式匹配(filename pattern matching),它允许用户使用特殊的通配符(wildcards)来匹配多个文件,而不需要手动列出所有文件名。这一功能是 Shell 解析命令时的一个重要步骤,极大地提高了命令行操作的灵活性。


1. 什么是 Globbing?

Globbing 是 Shell 解释用户输入的命令时,将包含通配符的模式 扩展为符合匹配规则的文件名列表 的过程。例如:

ls *.txt

在执行 ls *.txt 时,Shell 不会将 *.txt 直接传递给 ls,而是会 先解析 *.txt 并匹配当前目录下的所有 .txt 文件,然后把结果传递给 ls 命令。例如,当前目录下有:

file1.txt file2.txt file3.log

则:

ls *.txt

实际上等价于:

ls file1.txt file2.txt

其中 file3.log 因不符合 *.txt 的模式匹配规则而被排除。


2. Globbing 的常见通配符

Shell 的 globbing 机制支持多种 通配符(wildcards),常见的有以下几种:

通配符作用示例匹配内容
*匹配 任意数量 的字符(包括 0 个字符)*.txta.txtb.txttest.txt
?匹配 任意单个字符file?.txtfile1.txtfile2.txt,但不匹配 file10.txt
[abc]匹配 [] 内的 任意一个字符file[12].txtfile1.txtfile2.txt
[a-z]匹配 某个范围内的字符file[a-z].txtfilea.txtfileb.txt
{a,b,c}匹配 逗号分隔的任意一个模式file{1,2,3}.txtfile1.txtfile2.txtfile3.txt
** (仅 Bash 4.0+)递归匹配所有子目录**/*.txt匹配当前目录及所有子目录中的 .txt 文件

3. Globbing 的执行流程

在 Shell 处理用户输入的命令时,globbing 是命令解析(parsing)过程中的一个步骤。执行流程如下:

  1. 用户输入命令(例如 ls *.txt)。
  2. Shell 解析命令
    • 如果命令行包含通配符(如 *),Shell 进入 globbing 处理
    • Shell 读取当前目录下的文件列表,并 匹配符合规则的文件名
  3. Shell 替换通配符模式
    • *.txt 被替换为所有匹配的文件名,如 file1.txt file2.txt
  4. Shell 执行最终命令
    • ls file1.txt file2.txt

注意:如果没有任何文件匹配通配符模式,大多数 Shell 会直接返回原始模式,如:

echo *.xyz

如果 *.xyz 没有匹配的文件,Bash 会直接输出 *.xyz,而不会报错。


4. Globbing 与 正则表达式 的区别

Globbing 并不是正则表达式,它们有以下主要区别:

特性Globbing正则表达式
作用文件名匹配处理文本模式匹配
* 含义匹配 任意字符(包括空字符)匹配 前一个字符 0 次或多次
? 含义匹配 任意单个字符匹配 前一个字符 0 或 1 次
. 含义作为普通字符匹配代表 任意单个字符

示例:

ls *.txt    # 使用 globbing,匹配所有 .txt 结尾的文件
grep 'a.*b' file.txt   # 使用正则表达式,匹配 'a' 到 'b' 之间的任何字符

5. 禁用 Globbing

有时候,我们希望 Shell 不要 自动展开通配符,而是让命令接收到原始的 *? 等字符。可以使用以下方法:

  1. 使用单引号 ''
    echo '*.txt'  # 输出 *.txt,而不是匹配的文件列表
    
  2. 使用 set -f 关闭 globbing
    set -f
    echo *.txt   # 直接输出 *.txt
    set +f       # 重新开启 globbing
    

6. Shell 中的 Globbing 实现

Globbing 在 Shell 内部是如何实现的呢?主要分为以下几步:

  1. 读取命令:Shell 读取用户输入的命令字符串。
  2. 解析通配符
    • 遍历当前目录文件列表。
    • 依次对文件名进行 模式匹配(Pattern Matching)。
    • 使用 字符串匹配算法 进行匹配,如:
      • * 进行贪心匹配(Greedy Match)。
      • ? 进行单字符匹配。
      • [a-z] 进行范围匹配。
  3. 替换匹配项
    • 匹配的文件列表替换原始通配符字符串。
  4. 执行命令:Shell 执行替换后的命令。

Shell 通常使用 系统调用 opendir()readdir() 访问目录并进行匹配。


7. 编写 C 代码实现简单的 Globbing

下面是一个使用 fnmatch() 函数进行 Shell 风格模式匹配的 C 代码示例:

具体原理和代码解析请看笔者的另一篇博客: 深入解析 fnmatch():C 语言中的模式匹配函数(中英双语)

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <fnmatch.h>

void list_matching_files(const char *pattern) {
    struct dirent *entry;
    DIR *dir = opendir(".");
    
    if (!dir) {
        perror("opendir");
        return;
    }

    while ((entry = readdir(dir)) != NULL) {
        if (fnmatch(pattern, entry->d_name, 0) == 0) {
            printf("%s\n", entry->d_name);
        }
    }
    
    closedir(dir);
}

int main() {
    list_matching_files("*.c");  // 匹配当前目录下的所有 .c 文件
    return 0;
}

运行示例

$ gcc globbing.c -o globbing
$ ./globbing
main.c
utils.c
shell.c

8. 结论

Globbing 是 Shell 解析命令的重要步骤,主要用于 文件名匹配,其实现涉及 字符串匹配算法、系统目录读取 等技术。用户可以利用 通配符 灵活地批量操作文件,但要注意它与 正则表达式 的区别。此外,用户可以通过 单引号set -f 禁用 Globbing,使 Shell 直接传递原始字符串。理解 Globbing 的原理可以帮助我们更高效地使用 Shell 命令,提高自动化任务的执行效率。


这篇博客详细介绍了 Globbing 的概念、用法、实现原理、C 代码示例,希望能帮助你更深入地理解这个 Shell 机制! 🚀

Shell Globbing: Principles, Usage, and Implementation

Globbing in Unix Shell (such as Bash, Zsh) refers to filename pattern matching, where users can use special wildcard characters to match multiple files without manually listing their names. This feature enhances the flexibility of command-line operations.


1. What is Globbing?

Globbing is the process where the Shell expands wildcard patterns into matching filenames before executing a command.

For example, consider the command:

ls *.txt

Instead of passing *.txt as an argument to ls, the Shell first expands the pattern by searching for files in the current directory that match the pattern. If the directory contains:

file1.txt file2.txt file3.log

then the command:

ls *.txt

is actually executed as:

ls file1.txt file2.txt

while file3.log is ignored because it does not match *.txt.


2. Common Wildcards in Globbing

Shell globbing supports several wildcards for flexible pattern matching:

WildcardDescriptionExampleMatches
*Matches any number of characters (including none)*.txta.txt, b.txt, test.txt
?Matches any single characterfile?.txtfile1.txt, file2.txt (not file10.txt)
[abc]Matches any single character in bracketsfile[12].txtfile1.txt, file2.txt
[a-z]Matches any character in the rangefile[a-z].txtfilea.txt, fileb.txt
{a,b,c}Matches any of the comma-separated patternsfile{1,2,3}.txtfile1.txt, file2.txt, file3.txt
** (Bash 4.0+)Recursively matches files in subdirectories**/*.txtAll .txt files in the directory tree

3. How Globbing Works Internally

When a user enters a command, Shell processing follows these steps:

  1. User inputs a command (e.g., ls *.txt).
  2. Shell scans for wildcards:
    • If a command argument contains a wildcard (*, ?, etc.), Shell performs globbing.
    • It retrieves the list of files in the current directory.
    • It matches filenames against the pattern.
  3. Shell replaces the pattern with matching filenames:
    • If *.txt matches file1.txt file2.txt, the final command becomes:
      ls file1.txt file2.txt
      
  4. Shell executes the command.

Note: If no files match, some shells return the original pattern (e.g., echo *.xyz outputs *.xyz).


4. Difference Between Globbing and Regular Expressions

Globbing is not the same as regular expressions. Key differences:

FeatureGlobbingRegular Expressions
PurposeMatches filenamesMatches text patterns
*Matches any charactersMatches previous character zero or more times
?Matches one characterMatches previous character zero or one time
.Treated as a normal characterMatches any character

Example:

ls *.txt         # Uses globbing to list all .txt files
grep 'a.*b' file.txt  # Uses regex to match 'a' followed by 'b'

5. Disabling Globbing

To prevent Shell from expanding wildcards, use:

  1. Single quotes (''):
    echo '*.txt'  # Outputs *.txt without expansion
    
  2. Disable globbing with set -f:
    set -f
    echo *.txt   # Outputs *.txt
    set +f       # Re-enables globbing
    

6. How Globbing is Implemented in Shell

Internally, globbing is handled in these steps:

  1. Shell reads the command string.
  2. Pattern matching against directory contents:
    • It retrieves files using system calls like opendir() and readdir().
    • It applies pattern matching algorithms.
  3. Matches are substituted before executing the command.

7. Implementing Globbing in C

The following C program demonstrates pattern matching using fnmatch(), which applies glob-style matching:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <fnmatch.h>

void list_matching_files(const char *pattern) {
    struct dirent *entry;
    DIR *dir = opendir(".");
    
    if (!dir) {
        perror("opendir");
        return;
    }

    while ((entry = readdir(dir)) != NULL) {
        if (fnmatch(pattern, entry->d_name, 0) == 0) {
            printf("%s\n", entry->d_name);
        }
    }
    
    closedir(dir);
}

int main() {
    list_matching_files("*.c");  // Matches all `.c` files in the directory
    return 0;
}

Example Output

If the directory contains main.c utils.c shell.c, running:

$ gcc globbing.c -o globbing
$ ./globbing
main.c
utils.c
shell.c

8. Conclusion

Globbing is a key feature of Shell parsing, allowing users to efficiently match filenames using wildcards. It differs from regular expressions and is processed before executing commands. Understanding globbing helps users write more efficient command-line operations and scripts. It is implemented at the Shell level using directory scanning and pattern matching algorithms.

Mastering globbing enables more effective batch file operations, automation, and scripting in Unix-based systems! 🚀

后记

2025年2月4日于山东日照。在GPT4o大模型辅助下完成。


http://www.kler.cn/a/532726.html

相关文章:

  • swagger使用指引
  • 架构规划之任务边界划分过程中承接分配
  • openRv1126 AI算法部署实战之——Tensorflow模型部署实战
  • PVE纵览-解锁 PVE 的潜力:配置显卡直通
  • pytorch实现长短期记忆网络 (LSTM)
  • 深度学习 Pytorch 基础网络手动搭建与快速实现
  • DeepSeek相关技术整理
  • 基于RTOS的STM32游戏机
  • 电商项目高级篇09-检索服务
  • Linux find 命令 | grep 命令 | 查找 / 列出文件或目录路径 | 示例
  • 2025美赛赛前准备笔记(论文手)
  • 【IoCDI】_@Bean的参数传递
  • leetcode 901. 股票价格跨度
  • 【玩转 Postman 接口测试与开发2_016】第13章:在 Postman 中实现契约测试(Contract Testing)与 API 接口验证(上)
  • 【25考研】南开软件考研复试复习重点!
  • redis实现延迟任务
  • 结构体排序 C++ 蓝桥杯
  • C++引用练习题
  • 基于springboot的电影评论网站(源码+数据库+文档)
  • PVE纵览-实现极致性能:在Proxmox VE中配置硬盘直通
  • Office / WPS 公式、Mathtype 公式输入花体字、空心字
  • 【C# 】图像资源的使用
  • 结合 vim-plug 安装并使用 Gruvbox 主题教程
  • 使用Posix共享内存区实现进程间通信
  • 二维数组 C++ 蓝桥杯
  • vue生命周期及其作用