使用Bash脚本通过egrep实现邮箱与手机号搜索选项时无响应问题排查
排查Bash脚本无输出的问题
咱们来拆解你的脚本里的几个关键错误,正是这些问题导致它没产生预期结果:
1. Getopts用法完全错误
你写的while getopts "::-e:-p:" option完全不符合getopts的语法规则:
- getopts的选项字符串只需要写选项字符,不需要带短横线,比如
-e对应字符e,-p对应p - 带冒号
:表示该选项需要接收参数(比如你的文件名),所以正确的选项字符串应该是"e:p:" - 对应的case分支里,应该匹配
e和p,而不是-e和-p——因为getopts返回的是去掉短横线的选项字符
2. 参数引用方式不对
你用$2来获取目标文件名,但$2是脚本的第二个位置参数,一旦选项顺序变化(比如./yourscript.sh -p file.txt),虽然这里$2是对的,但如果有其他参数干扰就会出错。getopts会自动把选项对应的参数存到$OPTARG变量里,用它才是标准且可靠的做法。
3. 正则表达式的小bug
- 邮箱正则:你写的
.[a-zA-Z0-9.-]+里的.没有转义,在正则中.会匹配任意字符,应该写成\.[a-zA-Z0-9.-]+,否则会匹配到不符合邮箱格式的内容,甚至漏匹配正确的邮箱。 - 电话号码正则:你用了
^和$锚定整行,这意味着只有当电话号码单独占一行时才会被匹配。如果电话号码和其他文本在同一行(比如联系我:(123) 456-7890),就完全匹配不到。换成单词边界\b就能解决这个问题。
修正后的脚本
#!/bin/sh while getopts "e:p:" option; do case $option in e) # 匹配邮箱,修正了.的转义 egrep -o "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" "$OPTARG" ;; p) # 匹配电话号码,去掉行锚定换成单词边界 egrep -o "\b((\([0-9]{3}\) )|([0-9]{3}-))[0-9]{3}-[0-9]{4}\b" "$OPTARG" ;; \?) # 处理无效选项 echo "Invalid option: -$OPTARG" >&2 exit 1 ;; :) # 处理选项缺少参数的情况 echo "Option -$OPTARG requires a filename as argument." >&2 exit 1 ;; esac done
测试方式
比如你要搜索test.txt里的邮箱,就运行:
./yourscript.sh -e test.txt
搜索电话号码则运行:
./yourscript.sh -p test.txt
内容的提问来源于stack exchange,提问作者jimmy matics




