如何在 shell 脚本中使用正则表达式?
Posted
技术标签:
【中文标题】如何在 shell 脚本中使用正则表达式?【英文标题】:How do I use a regex in a shell script? 【发布时间】:2016-06-25 10:50:33 【问题描述】:我正在尝试将字符串与 shell 脚本中的正则表达式匹配。 此字符串是脚本的参数 ( $1 ),它是日期 (MM/DD/YYYY) 我正在尝试使用的正则表达式是:
^\d2[\/\-]\d2[\/\-]\d4$
它似乎有效,我在几个正则表达式测试网站上尝试过。
我的shell代码是:
REGEX_DATE="^\d2[\/\-]\d2[\/\-]\d4$"
echo "$1" | grep -q $REGEX_DATE
echo $?
“回声$?”无论我放入参数中的字符串是什么,都返回 1。
你们有什么想法吗?
谢谢!
【问题讨论】:
这可能是***.com/questions/19737675/…的一种重复 那是因为$?
报告了管道链中的第一个命令,即 echo - echo 显然会成功,所以你会得到一个 1
退出代码。试试grep $pattern <<< $1
。
请参阅this question 了解一种解决方案。
始终检查您的程序文档以查看可接受的正则表达式样式。
@MarcB err,不,恰恰相反——$?
是管道中的最后一个退出状态
【参考方案1】:
补充现有的有用答案:
在这种情况下,使用 Bash 自己的正则表达式匹配运算符 =~
是一种更快的选择,因为您只匹配已经存储在变量中的单个值:
set -- '12-34-5678' # set $1 to sample value
kREGEX_DATE='^[0-9]2[-/][0-9]2[-/][0-9]4$' # note use of [0-9] to avoid \d
[[ $1 =~ $kREGEX_DATE ]]
echo $? # 0 with the sample value, i.e., a successful match
但请注意,使用特定风格的正则表达式结构(例如 \d
)的警告同样适用:
虽然=~
支持 ERE(扩展 正则表达式),但它也支持主机平台的特定扩展 - 这是 Bash 行为依赖于平台的罕见情况。
为了保持可移植性(在 Bash 的上下文中),请遵守 POSIX ERE 规范。
请注意,=~
甚至允许您定义 捕获组(带括号的子表达式),您以后可以通过 Bash 的特殊 $BASH_REMATCH[@]
数组变量访问其匹配项。
补充说明:
$kREGEX_DATE
使用 unquoted,这是识别正则表达式所必需的(引用的部分将被视为 文字)。 p>
虽然并非总是必要的,但建议先将正则表达式存储在变量中,因为 Bash 无法处理包含 \
的正则表达式 literals。
\<
支持匹配单词边界,[[ 3 =~ \<3 ]] && echo yes
不起作用,但 re='\<3'; [[ 3 =~ $re ]] && echo yes
可以。
我已将变量名称 REGEX_DATE
更改为 kREGEX_DATE
(k
表示(概念)常量),以确保名称不是全大写名称,因为 @987654322 @。
【讨论】:
【参考方案2】:我想这就是你想要的:
REGEX_DATE='^\d2[/-]\d2[/-]\d4$'
echo "$1" | grep -P -q $REGEX_DATE
echo $?
我使用 -P 开关来获取 perl 正则表达式。
【讨论】:
澄清一下,-P
不保证在所有发行版中都受支持。所以如果便携性是一个问题,你会想要避免它。
在这种情况下,@MikeFrysinger 的解决方案更可取。这个有点使用原始正则表达式的吸引力,给予或接受一些转义。【参考方案3】:
问题是您尝试使用 grep 不支持的正则表达式功能。即,您的 \d
将不起作用。改用这个:
REGEX_DATE="^[[:digit:]]2[-/][[:digit:]]2[-/][[:digit:]]4$"
echo "$1" | grep -qE "$REGEX_DATE"
echo $?
您需要-E
标志来获取ERE 才能使用#
样式。
【讨论】:
++;请注意,如果您\
-转义了
和
实例,则此特定正则表达式在没有 -E
的情况下也可以作为 BRE(基本正则表达式)工作;作为不可移植的旁白:BSD/OSX grep
- 不像 GNU grep
- 实际上确实支持 \d
。
你当然是对的;但是我更喜欢 -E
而不是到处都是 `` 因为它使代码更具可读性,并且它位于 POSIX 中。以上是关于如何在 shell 脚本中使用正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章