Skip to content

Shell 语法进阶:特殊符号与正则表达式

前半侧重交互式串联与引号;后半区分 文件名通配文本模式匹配


一、命令之间的逻辑关系

shell
cmd1 ; cmd2          # 顺序执行,互不影响
cmd1 && cmd2         # cmd1 成功才执行 cmd2
cmd1 || cmd2         # cmd1 失败才执行 cmd2

示例:ls ; cd /etc/ ; ls -als && cd /etc/ 等。


二、文件名通配符(Glob)

用于匹配路径名字符串(不少命令里未开启正则,用的是 glob):

符号含义
?单个任意字符
*零个或多个任意字符
[abc]括号内任一字符
[a-z]范围内任一字符
[^0-9]排除括号内所列

三、引号与替换

符号含义
''单引号:强引用,内容多为字面量
""双引号:可展开变量、$( )、部分转义
`反引号:命令替换(旧写法,易与引号嵌套混淆)
$( )命令替换(推荐)
$(( ))算术展开
#行注释
$变量引用

四、子 Shell:(){}

  • ( commands ):在子 Shell 中执行,变量等改动不影响当前 Shell。
  • { commands; }:在当前 Shell 执行;多条命令用 ; 分隔,最后一个命令后、} 前也要有分号(与 ( ) 不同);{ 与首个命令之间必须有空格。

区别简述

  • () 会启动子 Shell;{} 不启动。
  • () 里多条命令用 ; 分隔,最后一条可不加分号(仍建议统一加);{} 内通常最后也需 ;
  • 内外层重定向作用范围不同:块外的重定向作用于块内全部命令。

五、父 Shell 与子 Shell

在终端里输入 bash 可进入子 Shell,exit 返回;pstree 可观察进程树。脚本里 (...) 同理。


六、测试:[ ][[ ]]

[ ] 常与 test 等价;[[ ]] 是 Bash 关键字,支持更多模式匹配。变量测试时注意引号,例如 [ "$name" = "张三" ]


七、正则表达式与通配符的区别

  • 正则:在文本内容里找模式;常用于 grepsedawk(按具体选项与方言)。
  • 通配符(glob):多用在文件名匹配;lscp 等按路径展开规律不是正则。
  • find -name:后跟的是 glob 风格 的图案,不是扩展正则。

勿把 grep 里的 *(「前一个元素重复」)与文件名里的 * 混为一谈。


八、find 中的通配(按文件名找)

shell
find . -name "abc*"      # 以 abc 开头
find . -name "a?c"       # a + 一字 + c
# [] [^] 等同理

九、grep 与基本正则 / 扩展正则(示例)

grep 默认基本正则(BRE) 语境下(部分模式需转义):

模式含义
*前一个字符重复 0 次或多次
?(BRE 中常需写成 \?)前一个字符 0 或 1 次
[]括号内任一字符
^ / $行首 / 行尾
\{n\}重复次数
shell
grep "abc*" file1
grep '^abc' file1

扩展正则(ERE) 常用 grep -E

  • +:一次或多次
  • ?:0 或 1 次
  • |:分支
  • ():分组

实际使用时务必加 grep 手册grep -E / egrep 说明,因为 GNU 与 BSD 选项略有差异。


十、小结

  1. 先分清场景:是匹配文件名(glob / find -name)还是匹配日志内容(grep/sed/awk 正则)。
  2. Bash 参数展开 ${var/pattern/} 等属于 Shell 语法,与正则不是同一套规则。
  3. 复杂匹配优先在 grep -Eperl -nerg(ripgrep)里完成,可读性往往更好。