FreeBSD Bash - 无法使用正则表达式对条件进行编码

FreeBSD Bash - Unable to code a condition with regex

我正在尝试为基于 FreeBSD 的 pfSense 编写脚本。唯一给我带来麻烦的部分是正则表达式的条件。简化代码是这样的:

RESPONSE='{"port":98989}'
REG='{"port":([0-9]*)}'
if [[ $RESPONSE =~ $REG ]]; then
    PORT=${BASH_REMATCH[1]}
fi

启用跟踪模式后,错误 returned 如下:

+ RESPONSE='{"port":98989}'
+ REG='{"port":([0-9]*)}'
+ '[[' '{"port":98989}' '=~' '{"port":([0-9]*)}' ]]
./pia-port-v2: [[: not found

我不明白为什么 [[ 在跟踪中的单引号之间,这可能是 "not found" 错误发生的原因。

更新

可能是因为pfSense的FreeBSD不支持bash,这些说明只是bash。我发现在写完这个问题并试图找到答案之后。

有人可以替代伯恩 shell 吗?如果表达式匹配,目标是 return 端口号。

我对 unix 中的脚本编码很陌生,比如 OS。

同时,我查看了 grep,但它似乎只将正则表达式应用于文件输入。

使用 [[ 正则表达式(有时;不总是)时 ' 和 " 有问题,所以我会试试这个(这对我来说很好):

#!/bin/bash

REG=\{\"port\"\:\([0-9]\*\)\}  # This line is altered
RESPONSE='{"port":98989}'
if [[ $RESPONSE =~ $REG ]]; then
  echo funkar
fi

您应该可以使用 expr utility to do this, but note that it use Posix basic regexps,这意味着您需要用反斜杠将括号变成捕获:

response='{"port":98989}'
reg='{"port":\([0-9]*\)}'
port=$(expr "$response" : "$reg")

expr returns 如果正则表达式不匹配则失败,因此您可以使用 shell 条件来测试:

port=$(expr "$response" : "$reg") || { echo Failed; }

if ! port=$(expr "$response" : "$reg"); then
  # Do something on failure
fi

/bin/sh:

#!/bin/sh

response='{"port":98989}'
case $response in
    '{"port":'[0-9]*'}')
        port=${response#*:}     # {"port":98989} --> 98989}
        port=${port%'}'}        # 98989} --> 98989
esac

printf 'response %s yields port %s\n' "$response" "$port"

请注意,case 语句不使用正则表达式,而是使用 shell 文件名通配模式。因此,该模式只会匹配一个数字并触发伪造的字符串,如 {"port":0xxx}.

如果响应字符串是 JSON 文档:

$ response='{"port":98989}'
$ printf '%s\n' "$response" | jq .port
98989