shell通配符

Shell 通配符(Wildcard,也称 Globbing)是 Linux/Unix Shell(Bash、Zsh 等)最常用的功能之一。它的核心作用是在命令执行之前,由 Shell 自动展开匹配的文件名,而不是命令本身处理。例如:

ls *.txt

Shell 会先展开为:

ls a.txt b.txt c.txt

然后再执行 ls。因此 Shell 通配符 ≠ 正则表达式,它们的语法和使用场景不同。([Baeldung on Kotlin][1])


一、最常用的 5 种通配符

通配符 含义 示例
* 任意个字符(包括0个) *.log
? 任意一个字符 file?.txt
[] 字符集合 file[123].txt
[a-z] 字符范围 img[0-9].png
[!abc] 排除字符 file[!0].txt

二、高频使用场景

场景1:查找某一类文件(★★★★★)

例如:

ls *.txt

目录:

a.txt
b.txt
c.log

执行:

ls *.txt

结果:

a.txt
b.txt

再比如:

查看所有 Python 文件

ls *.py

查看所有 jpg

ls *.jpg

查看所有 shell

ls *.sh

这是日常使用最多的场景。


场景2:批量删除文件(★★★★★)

删除所有日志:

rm *.log

例如:

app.log
mysql.log
nginx.log

全部删除。

⚠️ 危险操作:

很多人误写:

rm *

会删除当前目录所有普通文件。

更危险:

rm -rf *

会把当前目录所有内容删掉。

生产环境建议先验证匹配结果:

echo *.log

确认无误后再执行删除。([Packt][2])


场景3:批量复制(★★★★★)

复制所有图片:

cp *.jpg backup/

复制所有配置:

cp *.conf /tmp/

复制所有 Python:

cp *.py project/

场景4:批量移动(★★★★★)

例如:

mv *.txt docs/

目录:

a.txt
b.txt
c.py

执行:

mv *.txt docs/

结果:

docs/
    a.txt
    b.txt
c.py

场景5:统计文件数量(★★★★☆)

统计 txt 数量:

ls *.txt | wc -l

统计 jpg:

ls *.jpg | wc -l

或者:

find . -name "*.txt" | wc -l

三、? 的高频场景

场景1:固定字符长度

例如:

a.txt
ab.txt
abc.txt

执行:

ls ?.txt

结果:

a.txt

因为:

?

只能匹配一个字符。


例如:

file1.txt
file2.txt
file10.txt

执行:

ls file?.txt

结果:

file1.txt
file2.txt

不会匹配

file10.txt

因为:

10

是两个字符。([Command in Line][3])


四、[] 高级匹配

例如:

file1.txt
file2.txt
file3.txt
file9.txt

执行:

ls file[12].txt

结果:

file1.txt
file2.txt

数字范围:

ls file[1-5].txt

匹配:

1
2
3
4
5

字母范围:

ls img[a-z].png

匹配:

imga.png
imgb.png

多个范围:

ls [A-Z]*.txt

表示:

以大写字母开头

例如:

Hello.txt
Test.txt

五、排除匹配

例如:

file1
file2
fileA

执行:

ls file[!12]

结果:

fileA

因为:

[!12]

表示:

不是1也不是2

六、组合使用

例如:

log202401.txt
log202402.txt
log202501.txt

查看:

ls log2024*.txt

结果:

log202401.txt
log202402.txt

例如:

ls img??.png

匹配:

img01.png
imgab.png

不会匹配:

img001.png

七、路径中的通配符

例如:

ls /var/log/*.log

查看:

/var/log

下面所有 log。

再例如:

cp /home/*/.bashrc backup/

复制所有用户目录下的 .bashrc。([Packt][2])


八、递归匹配(Bash)

默认:

*.txt

只匹配当前目录。

如果开启:

shopt -s globstar

可以:

ls **/*.txt

匹配:

当前目录
所有子目录
所有孙目录

全部 txt 文件。([Shell Tips!][4])


九、大括号 {}(容易与通配符混淆)

很多人认为:

*.{jpg,png,gif}

属于通配符。

实际上:

{}

Brace Expansion(花括号展开),不是 Globbing。

例如:

echo file{1,2,3}.txt

Shell 展开:

file1.txt
file2.txt
file3.txt

再例如:

ls *.{jpg,png}

Shell 实际展开为:

ls *.jpg *.png

然后每个模式再分别进行文件名匹配。([kindatechnical()][5])


十、最容易犯的错误

1. 通配符不是正则表达式

很多人写:

ls .*txt$

这是错误的。

Shell 不认识:

$
+
()

这些正则表达式元字符。


2. 引号会阻止通配符展开

例如:

echo "*.txt"

输出:

*.txt

不会展开。


3. Shell 先展开,再执行命令

例如:

echo *.txt

假设目录:

a.txt
b.txt

Shell 实际执行:

echo a.txt b.txt

因此,真正处理通配符的是 Shell,而不是 echols 等命令。([Baeldung on Kotlin][1])


十一、高频命令组合速查

场景 命令
查看所有 txt ls *.txt
删除所有日志 rm *.log
复制所有图片 cp *.jpg img/
移动所有 PDF mv *.pdf docs/
查找指定类型 find . -name "*.txt"
统计文件数量 ls *.txt | wc -l
查看固定长度文件 ls file?.txt
查看数字编号 ls img[0-9].png
排除某些字符 ls file[!0-9]
递归匹配(开启 globstar 后) ls **/*.log

建议掌握优先级: *(最高频)→ ?[]{}(花括号展开)→ **(递归匹配,需 Bash 支持)。掌握这几种模式后,已经能够覆盖绝大多数 Shell 日常文件操作场景。

posted @ 2026-07-13 10:09  ZovoeY  阅读(27)  评论(0)    收藏  举报