Linux命令行通配符和正则表达式

2025-12-17 19:40:00
丁国栋
原创 25
摘要:本文介绍一些关于Linux命令行通配符和正则表达式的知识。

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

重要区别

  1. Shell 通配符用于文件名扩展,由 shell 在处理命令前展开
  2. 正则表达式用于文本处理,由具体工具(grep, awk, sed)解析
  3. 大多数符号含义不同(如 . 在正则中表示任意字符,在通配符中就是点字符)

快速参考表

*       # 任意数量的任意字符(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/
发表评论
博客分类