我正在尝试编写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
,我应该使用什么变量来捕获正则表达式?
答案 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