如何在#!/bin/sh脚本的if语句中兼容使用正则表达式?
如何将bash风格的if语句修改为POSIX sh兼容版本
嘿,我来帮你搞定这个脚本兼容问题!原来的代码用了bash独有的扩展语法([[ ]]和=~正则匹配),而#!/bin/sh是遵循POSIX标准的shell,不支持这些特性,所以咱们得做两处关键修改:
1. 替换[[ ]]为POSIX标准的[ ]
bash的[[ ]]是扩展的条件测试语法,POSIX sh只认标准的[ ](也就是test命令的别名)。同时要注意给变量加上双引号,避免当$date为空时出现语法错误:
原来的:
if [[ -z $date ]]; then
改成:
if [ -z "$date" ]; then
2. 替换=~正则匹配为POSIX兼容的写法
POSIX sh没有=~这种正则匹配语法,咱们有两种常用的替代方案:
方案一:用case语句(推荐,纯内置命令,效率高)
case语句支持通配符匹配,刚好可以用来验证YYYY-MM-DD的格式:
修改后的完整代码:
if [ -z "$date" ]; then echo "No date argument" exit 1 elif case "$date" in # 匹配4位数字-2位数字-2位数字的格式 [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) true ;; *) false ;; esac; then # 这里放你原来的return逻辑 # 比如 return 0 或者其他操作 : fi
如果觉得把case嵌在elif里有点绕,也可以拆分出来,逻辑更清晰:
if [ -z "$date" ]; then echo "No date argument" exit 1 fi case "$date" in [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) # 格式匹配成功,执行你的逻辑 # return ... ;; *) # 如果需要处理格式不合法的情况,可以在这里加代码 ;; esac
方案二:用expr命令(支持更复杂的正则,但依赖外部命令)
如果需要更严格的正则验证(比如后续要扩展规则),可以用POSIX标准的expr命令:
if [ -z "$date" ]; then echo "No date argument" exit 1 elif expr "$date" : '^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}$' > /dev/null; then # 格式匹配成功,执行你的逻辑 # return ... fi
这里expr的:操作符用来做正则匹配,>/dev/null是把匹配结果(匹配到的字符数)丢弃,只关注命令的退出状态。
小提示
- 用
case的通配符虽然不能像正则那样验证月份/日期的有效性(比如02-30这种无效日期),但如果只是基础的格式检查,完全够用;如果需要更精确的日期验证,可能要额外写逻辑判断年、月、日的范围。 - 所有变量都加上双引号是POSIX shell的好习惯,能避免很多空值、特殊字符导致的语法问题。
内容的提问来源于stack exchange,提问作者Saeko
相关产品推荐
相关产品推荐

