Linux命令行通配符和正则表达式
- 2025-12-17 19:40:00
- 丁国栋
- 原创 25
Linux 命令行默认支持哪些类似正则表达式的通配符,如?, * [0-9]等。
Linux 命令行中支持多种通配符(globs/patterns),但这不是真正的正则表达式。以下是主要的匹配模式:
1. Shell 通配符(Globs)
基本通配符
-
*- 匹配任意数量的任意字符(包括0个)ls *.txt # 匹配所有 .txt 文件 -
?- 匹配单个任意字符ls file?.txt # 匹配 file1.txt, fileA.txt -
[]- 字符组,匹配方括号中的任意一个字符ls file[123].txt # 匹配 file1.txt, file2.txt, file3.txt ls [abc]*.txt # 匹配以 a,b,c 开头的 .txt 文件 -
[!]或[^]- 否定字符组ls file[!123].txt # 匹配不是 file1/2/3.txt 的文件
范围匹配
-
[0-9]- 匹配数字ls file[0-9].txt -
[a-z]- 匹配小写字母ls [a-z]* -
[A-Z]- 匹配大写字母 -
[a-zA-Z]- 匹配所有字母 -
[a-zA-Z0-9]- 匹配字母和数字
高级通配符(需要开启 extglob)
shopt -s extglob # 启用扩展通配符
-
?(pattern)- 匹配0次或1次ls file@(2020)?(.txt) # file 或 file.txt -
*(pattern)- 匹配0次或多次ls file*(.txt) # file, file.txt, file.txt.txt -
+(pattern)- 匹配1次或多次ls file+(.txt) # file.txt, file.txt.txt -
@(pattern|pattern)- 匹配其中一个模式ls file@(.txt|.log) # file.txt 或 file.log -
!(pattern)- 匹配除指定模式外的ls !(*.txt) # 所有非 .txt 文件
2. 真正的正则表达式工具
grep 系列
# 基本正则表达式
grep 'pattern' file
# 扩展正则表达式
grep -E 'pattern' file
# 或
egrep 'pattern' file
# Perl 风格正则表达式
grep -P 'pattern' file
sed(流编辑器)
sed -n '/pattern/p' file # 打印匹配行
sed 's/pattern/replacement/' # 替换
awk
awk '/pattern/ {print}' file
3. 文件查找中的正则表达式
find 命令
# -name 使用通配符
find . -name "*.txt"
# -regex 使用完整正则表达式
find . -regex ".*/[0-9][0-9]\.txt"
4. 常见正则表达式符号对照
| 用途 | Shell 通配符 | 正则表达式 |
|---|---|---|
| 任意字符 | ? |
. |
| 任意数量字符 | * |
.* |
| 字符组 | [abc] |
[abc] |
| 数字 | [0-9] |
[0-9] 或 \d |
| 非数字 | 无直接对应 | \D |
| 开头锚定 | 无 | ^ |
| 结尾锚定 | 无 | $ |
5. 示例对比
# Shell 通配符(匹配文件)
ls 3??.txt # 3开头,任意3个字符,.txt结尾
ls 3[0-9][0-9].txt # 3开头,两个数字,.txt结尾
# 正则表达式(在文本中搜索)
grep '^3[0-9][0-9]\.txt$' file
重要区别
- Shell 通配符用于文件名扩展,由 shell 在处理命令前展开
- 正则表达式用于文本处理,由具体工具(grep, awk, sed)解析
- 大多数符号含义不同(如
.在正则中表示任意字符,在通配符中就是点字符)
快速参考表
* # 任意数量的任意字符(shell通配符)
? # 单个任意字符(shell通配符)
[abc] # a,b,c中的任意一个(两者通用)
[^abc] # 不是a,b,c的任意字符(正则表达式)
[!abc] # 不是a,b,c的任意字符(shell通配符)
. # 任意单个字符(正则),普通点字符(shell通配符)
.* # 任意数量任意字符(正则)
^ # 行首(正则)
$ # 行尾(正则)
--
示例:写一个shell命令行,将某个目录下的以3xx.bkt格式的文件rsync到另一个目录,其中3xx.bkt格式中xx表示两位数字。
可以使用 rsync 配合通配符来实现这个需求。以下是几种实现方式:
方法1:直接使用通配符
rsync -av /源目录/3??.bkt /目标目录/
3??.bkt 会匹配 3 开头,后跟任意两个字符,最后是 .bkt 的文件
方法2:更精确的数字匹配
如果只想匹配数字(0-9),可以使用:
rsync -av /源目录/3[0-9][0-9].bkt /目标目录/
方法3:使用 find 命令(更灵活)
find /源目录 -name "3[0-9][0-9].bkt" -exec rsync -av {} /目标目录/ \;
方法4:使用 for 循环
for file in /源目录/3[0-9][0-9].bkt; do
if [ -f "$file" ]; then
rsync -av "$file" /目标目录/
fi
done
常用 rsync 选项说明
-a:归档模式,保留权限、时间戳等-v:显示详细输出-z:传输时压缩(适合慢速网络)--progress:显示传输进度--dry-run:试运行,不实际传输文件
示例
假设源目录是 /data/source,目标目录是 /data/backup:
rsync -av /data/source/3[0-9][0-9].bkt /data/backup/
发表评论