欢迎各位兄弟 发布技术文章
这里的技术是共享的
在 macOS(或任何 Unix-like 系统)的 shell 脚本中,[
(单中括号)和 [[
(双中括号)是条件测试的不同语法,主要区别如下:
[
是传统 test
命令的别名(相当于 test expression
或 [ expression ]
)。
兼容性更强,可在所有 POSIX shell(如 sh
、dash
)中使用。
需要严格的语法(如变量加引号、空格分隔符)。
不支持高级功能(如正则匹配、逻辑组合符 &&/||
直接使用)。
bash# 检查文件是否存在 if [ -f "/path/to/file" ]; then echo "文件存在" fi # 字符串比较(需加引号) name="hello" if [ "$name" = "hello" ]; then echo "字符串匹配" fi # 算术比较(需用 -eq/-lt 等) if [ "$num" -gt 10 ]; then echo "num 大于 10" fi
[[
是 Bash/Zsh 等现代 shell 的扩展功能(非 POSIX 标准)。
更灵活:
变量无需加引号(自动处理空格)。
支持逻辑组合符 &&
、||
(无需转义)。
支持模式匹配(==
通配符)和正则匹配(=~
)。
通常比 [
更高效(由 shell 直接解析,不调用外部命令)。
bash# 字符串比较(无需引号) if [[ $name == hello ]]; then echo "字符串匹配" fi # 模式匹配(通配符) if [[ "$file" == *.txt ]]; then echo "是 .txt 文件" fi # 正则匹配 if [[ "$email" =~ ^[a-z]+@[a-z]+\.[a-z]+$ ]]; then echo "邮箱格式有效" fi # 逻辑组合 if [[ -f "$file" && "$num" -gt 10 ]]; then echo "文件存在且 num > 10" fi
特性 | [ (单中括号) | [[ (双中括号) |
---|---|---|
兼容性 | POSIX(通用) | Bash/Zsh(非 POSIX) |
变量引号 | 必须加引号 | 可省略 |
逻辑操作符 | -a /-o (或转义) | 直接使用 && /` |
模式匹配 | 不支持 | 支持 == 、=~ |
错误处理 | 更严格(易报错) | 更容错 |
用 [[
:当脚本确定运行在 Bash/Zsh 环境时(更简洁、安全)。
用 [
:需要兼容 纯 POSIX shell(如 /bin/sh
)时。
在 macOS 的默认 shell(Zsh 或 Bash)中,推荐优先使用 [[
。
if [[ "$file" == *.txt ]]; 其中 *.txt 是正则表达式吗
在 [[ "$file" == *.txt ]]
中,*.txt
不是正则表达式,而是 shell 的通配符模式(glob pattern)。
特性 | 通配符 (Glob) | 正则表达式 (Regex) |
---|---|---|
用途 | 匹配文件名/字符串 | 匹配文本模式 |
语法 | 简单(* , ? , [] ) | 复杂(.* , + , \d 等) |
示例 | *.txt → 所有 .txt 文件 | ^[a-z]+\.txt$ → 字母开头的 .txt |
通配符 *.txt
*
匹配任意字符(包括空字符)。
示例:[[ "$file" == *.txt ]]
检查 $file
是否以 .txt
结尾,如 file.txt
、a.txt
。
正则表达式 =~
需用 =~
操作符显式启用正则匹配。
示例:[[ "$file" =~ ^.*\.txt$ ]]
(等价于通配符 *.txt
,但写法复杂)。
==
)bashfile="document.txt" if [[ "$file" == *.txt ]]; then echo "是 .txt 文件(通配符匹配)" fi
=~
)bashfile="123.txt" if [[ "$file" =~ ^[0-9]+\.txt$ ]]; then echo "是纯数字开头的 .txt 文件(正则匹配)" fi
[[ ... == *.txt ]]
是通配符,不是正则!
若想用正则,必须明确写 =~
,例如:
bash[[ "$file" =~ .*\.txt ]] # 正则写法(功能等效于 `*.txt` 通配符)
==
+ *.txt
→ 通配符模式(简单文件名匹配)。
=~
+ .*\.txt
→ 正则表达式(复杂文本模式匹配)。
在判断文件扩展名时,直接用通配符(== *.txt
)更简洁;若需更复杂的模式(如数字开头),才用正则(=~
)。