Linux 命令行通配符是 shell 提供的一种强大功能,允许用户通过简化的模式匹配来批量操作文件和目录,从而避免逐个输入长文件名,极大提升工作效率,通配符的核心作用在于“模糊匹配”,即使用特定的元字符(通配符)代替一个或多个字符,shell 会在执行命令时自动将这些元字符展开为匹配的实际文件名列表,理解通配符的规则和使用场景,是熟练掌握 Linux 命令行操作的重要基础。

Linux 常用的通配符主要包括星号()、问号(?)、方括号([])和花括号({}),每种通配符都有其独特的匹配逻辑,星号()是最常用且功能最强大的通配符,用于匹配任意长度的任意字符,包括零个字符,命令 ls *.txt
会列出当前目录下所有以 .txt
结尾的文件,无论文件名中间有多少字符;ls backup*
则会匹配所有以 backup
开头的文件,如 backup1.log
、backup_final.tar
等,需要注意的是,星号不会匹配以点(.)开头的隐藏文件,除非显式指定,ls .*
才能匹配隐藏文件(如 .bashrc
),而 ls *
会忽略隐藏文件。
问号(?)的匹配规则比星号更严格,它仅匹配单个任意字符,但不包括零个字符。ls ?.txt
会匹配单个字符加 .txt
的文件,如 a.txt
、txt
,但不会匹配 ab.txt
(因为文件名有两个字符)或 .txt
(因为零个字符不匹配),当需要匹配固定长度的文件名时,问号非常有用,ls image????.jpg
可以匹配所有 image
开头、后跟 4 个字符并以 .jpg
结尾的图片文件(如 image1234.jpg
),但不会匹配 image12.jpg
(字符不足)或 image12345.jpg
(字符超长)。
方括号([])用于匹配指定范围内的单个字符,支持字符或数字的范围,也可以结合连字符(-)表示连续范围。ls file[1-3].txt
会匹配 file1.txt
、file2.txt
、file3.txt
;ls report[A-Z].log
会匹配 reportA.log
到 reportZ.log
(大写字母范围);ls data[0-9a-z].dat
会匹配 data
后跟单个数字(0-9)或小写字母(a-z)再加 .dat
的文件,方括号还支持取反匹配,即在方括号内开头加上感叹号(!)或脱字符(^),ls file[!1-3].txt
会匹配除 file1.txt
、file2.txt
、file3.txt
之外的所有 .txt
文件,方括号的匹配是精确的单字符匹配,不会像星号那样匹配多个字符。
花括号({})与其他通配符不同,它主要用于生成多个字符串模式,常用于批量创建文件或目录,或一次性操作多个目标,花括号内的字符串用逗号分隔,shell 会将其展开为多个独立的路径。touch {file1,file2,file3}.txt
会创建 file1.txt
、file2.txt
、file3.txt
三个文件;mkdir -p {project/{src,bin,test},docs}
会递归创建 project/src
、project/bin
、project/test
和 docs
四个目录,花括号还支持嵌套和范围,echo {1..5}
会输出 1 2 3 4 5
,echo {a..e}
会输出 a b c d e
,echo {1..3}{a..c}
会输出 1a 1b 1c 2a 2b 2c 3a 3b 3c
,需要注意的是,花括号的展开是字符串层面的,不会自动匹配文件系统中的实际文件,除非与通配符结合使用,ls {*.log,*.txt}
会同时列出所有 .log
和 .txt
文件。

在实际使用中,通配符的优先级和组合使用需要注意,通常情况下,花括号({})的展开优先级最高,其次是方括号([]),然后是问号(?),最后是星号(),`ls {.log,.txt}中花括号会先展开为
.log .txt,再由星号匹配文件,如果需要匹配包含特殊字符的文件名(如文件名中包含星号、问号等),可以使用反斜杠(\)进行转义,例如
ls file*.txt会匹配名为
file.txt的文件(而不是所有以
file开头、后跟任意字符、以
.txt结尾的文件),在脚本中使用通配符时,需要注意文件名中的空格或特殊字符可能导致错误,建议使用引号将通配符表达式括起来,例如
ls "*.txt"` 可以确保文件名中的空格不会被误解为多个参数。
以下表格总结了 Linux 常用通配符的匹配规则及示例:
通配符 | 名称 | 匹配规则 | 示例 | 匹配结果示例 |
---|---|---|---|---|
星号 | 任意长度的任意字符(包括零字符) | ls *.log |
error.log 、access2023.log |
|
问号 | 单个任意字符(不包括零字符) | ls ?.txt |
a.txt 、txt |
|
[] | 方括号 | 指定范围内的单个字符 | ls file[1-3].txt |
file1.txt 、file2.txt |
[!x] | 方括号取反 | 不包含指定字符的单个字符 | ls file[!0-9].txt |
filea.txt 、fileX.txt |
花括号 | 生成多个字符串模式 | touch {a,b}.log |
创建 a.log 、b.log |
通配符的合理使用可以显著简化命令行操作,但同时也可能带来风险,在执行删除操作时,如果误用通配符,可能会导致重要文件被误删,命令 rm *.tmp
会删除所有 .tmp
文件,但如果当前目录下有一个名为 important_file.tmp
的文件,它也会被删除,且无法恢复,在执行危险操作前,建议先使用 ls
命令查看通配符的匹配结果,确认无误后再执行,可以先运行 ls *.tmp
查看将要删除的文件列表,确认无误后再执行 rm *.tmp
。
不同 shell(如 Bash、Zsh、Fish)对通配符的支持可能略有差异,Zsh 支持更高级的通配符功能,如 递归匹配子目录中的文件,ls **/*.txt
可以递归查找当前目录及子目录下所有 .txt
文件,而 Bash 默认不支持递归匹配,需要结合 find
命令实现类似功能,find . -name "*.txt"
,了解所用 shell 的通配符特性,可以更灵活地处理复杂场景。

在编写 shell 脚本时,通配符的展开行为也需要特别注意,默认情况下,shell 会在执行命令前展开通配符,如果匹配不到任何文件,通配符会保持原样(ls *.nonexistent
会直接输出 *.nonexistent
,而不是报错),为了避免这种情况,可以使用 nullglob
选项(在 Bash 中通过 shopt -s nullglob
启用),当通配符匹配不到文件时,会展开为空字符串,避免命令参数错误,启用 nullglob
后,for file in *.nonexistent; do echo $file; done
循环不会执行任何操作,而不会输出 *.nonexistent
。
相关问答FAQs:
*Q1:为什么我的命令 `ls .txt没有列出隐藏文件,如
.hidden.txt?** A:Linux 中,星号(*)通配符默认不会匹配以点(.)开头的隐藏文件,这是因为隐藏文件通常用于配置文件或临时文件,避免在常规文件列表中显示,如果需要列出隐藏文件,可以使用两种方法:一是显式指定点号,如
ls .(但会同时列出
.和
..目录,建议使用
ls ..txt);二是使用
ls -a或
ls --all选项,它会显示所有文件(包括隐藏文件),此时
ls -a *.txt也会匹配隐藏文件,因为
-a` 选项会覆盖通配符的默认隐藏文件过滤行为。
*Q2:如何使用通配符匹配文件名中包含星号()或问号(?)的实际文件?*
A:如果文件名中包含星号、问号等通配符字符,而希望匹配这些字面字符而非通配符功能,可以使用反斜杠(\)进行转义,要匹配名为 `filetxt的文件,应使用
ls file*2023.txt,其中
*会被视为字面星号,而不是通配符,在 Bash 中,也可以使用双引号将通配符表达式括起来,例如
ls "file*2023.txt"`,此时双引号内的星号会失去通配符含义,仅作为普通字符处理,转义和引用是避免通配符意外展开的重要方法,尤其在处理包含特殊字符的文件名时非常实用。