在 shell 脚本中可以使用哪些正则表达式方法来验证输入?

030*_*030 5 shell-script regular-expression test

#!/bin/sh

re="\/$"

if [ $1 =~ $re ]; then
        echo "${ATTENTION_PREFIX}$1 DIRECTORY MAY NOT CONTAIN A \"/\" OR LITERAL SLASH!${ATTENTION_POSTFIX}"
        exit 1
fi
Run Code Online (Sandbox Code Playgroud)

执行sudo file.sh hello/结果[: 29: hello: unexpected operator

看起来这个正则表达式方法对于 shell 脚本是不正确的。

Sté*_*las 8

标准test命令也称为[没有=~运算符。现在大多数 shell 都内置了该命令。

Korn shell 引入了具有替代语法和不同解析规则的[[...]]构造(不是[[命令)。

zshbash在一定程度上复制了它,但有限制和许多差异,但从未标准化,因此不应在可移植sh脚本中使用。

ksh93 总是有办法将扩展的正则表达式转换为它的全局变量:

printf '%P\n' "regexp"
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

[[ $var = pattern ]]
Run Code Online (Sandbox Code Playgroud)

后来(在 2001 年到 2003 年之间的某个时间),它还在其 glob 中加入了正则表达式,就像~(E)regex扩展正则表达式的语法一样,所以你可以这样做:

[[ $var = ~(E)pattern ]]
Run Code Online (Sandbox Code Playgroud)

这种模式匹配仅适用于[[...]]构造 or case,不适用于[命令。

zsh为其[命令添加了正则表达式匹配运算符,并[[...]]在 2001 年首次使用pcre模块添加了正则表达式匹配运算符。语法最初是[ string -pcre-match regex ][[ string -pcre-match regex ]]

bash=~在 bash 3.0(2004 年)中添加了一个运算符。使用扩展正则表达式。不久之后,ksh93 和 zsh 也添加了它(同样存在差异)。

ksh93bash-3.1以上使用引号来转义正则表达式运算符,导致各种混乱,这意味着它不能与[那里的命令一起使用。zsh没有那个问题(引号用于 shell 引用,反斜杠像往常一样用于转义正则表达式运算符),因此=~运算符在zsh[命令中工作(尽管它本身需要引用,因为=foo在 中是通配符zsh)。

yash(一个小的 POSIX shell)没有,[[...]]但它的[命令有一个=~运算符(使用 ERE)并且按您的预期工作(如zsh's)。

在任何情况下,POSIX[[...]]也不=~是,应该在sh脚本中使用。对字符串进行正则表达式匹配的标准命令是expr

if expr "x$var" : "x$regex" > /dev/null; then...
Run Code Online (Sandbox Code Playgroud)

请注意,expr正则表达式在开始时就被锚定,您需要使用该x技巧来避免$var作为expr运算符的值出现问题。

但是,大多数情况下,您不需要正则表达式,因为对于大多数情况,简单的 shell 模式匹配就足够了:

case $var in
  (pattern) echo matches
esac
Run Code Online (Sandbox Code Playgroud)


Jos*_*lly 6

更改#!/bin/sh#!/bin/bash,并使用双括号代替:

if [[ $1 =~ $re ]]; then
Run Code Online (Sandbox Code Playgroud)

这是扩展测试命令,与(常规)测试命令相反。=~只能与[[ ... ]]版本一起使用,并且需要 Bash 3.0 或更高版本。


cuo*_*glm 5

bash旧测试[中不支持正则表达式。您必须改用新测试[[

re="\/$"

if [[ $1 =~ $re ]]; then
        echo "${ATTENTION_PREFIX}$1 DIRECTORY MAY NOT CONTAIN A \"/\" OR LITERAL SLASH!${ATTENTION_POSTFIX}"
        exit 1
fi
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到更多。

您还需要将#!/bin/shshebang 行更改#!/bin/bash为 。