在sh脚本中捕获正则表达式组

时间:2018-06-20 17:52:06

标签: shell sh

我正在尝试编写Shell脚本,默认解释器为/bin/sh

我的脚本如下:

echo "Starting watchdog"
INFO=$(cat /tmp/info)
RE="s\=([0-9]+)"
if [[$INFO =~ $RE]]; then
echo ${BASH_REMATCH[1]};
fi

我收到这样的错误test.sh: line 6: [[do: not found

我假设${BASH_REMATCH[1]};是不正确的,但是如果我使用sh而不是bash,我应该使用什么变量来捕获正则表达式?

3 个答案:

答案 0 :(得分:0)

根本没有/bin/sh与此功能等效。

考虑使用awk

awk -F= '/s=[[:digit:]]+$/ { print $2; exit(0); }' </tmp/info

答案 1 :(得分:0)

您看到的错误是因为您未正确使用bash条件。 [[命令前后需要空格。它不仅是一种语言构造,而且是实际的 command ,它将您的部分条件作为选项。就是说,这是一个仅作为bash内置命令存在的命令,不是您可以在普通POSIX shell脚本中使用的命令。

用于处理带正则表达式条件的标准POSIX方法是shell脚本中的变量,expr(1)。也就是说,如果您要解析文件,则grep是经典的文件。

避免暴力行为,您可以执行以下操作:

#!/bin/sh

RE="s\=([0-9]+)"

if egrep "$RE" /tmp/info >/dev/null; then
  printf 'Found it!\n'
fi

或者如果您真的想使用您的$INFO变量来做到这一点:

#!/bin/sh

INFO="$(cat /tmp/info)"
RE='.*s=[0-9][0-9]*'

if expr "$INFO" : "$RE" >/dev/null; then
  printf 'Found it!\n'
fi

请注意调整后的RE,因为expr自动锚定到您输入的开头,并且仅使用BRE而不是ERE。

现在...如果您需要提取括号中似乎要获取的,则需要进行更多的解析。

#!/bin/sh

RE="s=([0-9]+)"

output="$(egrep -o "$RE" /tmp/info | head 1)"  #  fetch the output, if any
output="${output#s=}"                          #  strip off the "s=" at the beginning

if [ -n "$output" ]; then                      #  if we found anything...
  printf 'Found it: %s!\n' "$output"           #  print it!
fi

请注意使用egrep来解析ERE,而不是默认的BRE。根据您的环境进行调整。 (我了解到,有些Linuces倾向于推荐egrep反对grep -E。)

还请注意,如果您尝试从看起来更像abc=foo&jobs=5&s=important+data的输入数据中捕获某些内容,则使用与上述类似的RE可能会导致结果不理想。

答案 2 :(得分:0)

POSIX shell的内置case语句具有pattern matching模式匹配的功能不如 regex 强大,但是它可以匹配RE="s\=([0-9]+)"之类的简单内容。

例如,如果$n变量中有数字,则匹配:

n=number1 m= ; \
case "$n" in *[0-9]*) ;; *) m="not " ;; esac; printf 'number %sfound\n' "$m"

输出:

number found

无数字:

n=number m= ; \
case "$n" in *[0-9]*) ;; *) m="not " ;; esac ; printf 'number %sfound\n' "$m"

输出:

number not found

就是这样,并且在一定范围内甚至可以将模式放入变量中:

n=number1 m= p='[0-9]'; \
case "$n" in *$p*) ;; *) m="not " ;; esac ; printf 'number %sfound\n' "$m"

输出:

number found