FreeBSD Bash - невозможно кодировать условие с помощью регулярного выражения - PullRequest
0 голосов
/ 30 июня 2018

Я пытаюсь написать скрипт для pfSense, который основан на FreeBSD. Единственная оставшаяся часть, которая доставляет мне неприятности - это условие с регулярным выражением. Упрощенный код такой:

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

При включенном режиме трассировки возвращается следующая ошибка:

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

Я не понимаю, почему [[ находится между одинарными кавычками в трассировке, и, вероятно, поэтому возникает ошибка "not found".

Обновление

Вероятно, это связано с тем, что FreeBSD pfSense не поддерживает bash, и эти инструкции предназначены только для bash. Я нашел это после того, как написал этот вопрос и попытался найти ответ.

У кого-нибудь есть альтернатива оболочке Борна? Цель состоит в том, чтобы вернуть номер порта, если выражение совпадает.

Я новичок в написании сценариев в Unix, таких как ОС.

В то же время я смотрю на grep, но, похоже, он применяет регулярные выражения только к вводу файлов.

Ответы [ 3 ]

0 голосов
/ 30 июня 2018

Вы можете использовать утилиту expr для этого, но учтите, что она использует Posix basic regexps , что означает, что вам нужно чтобы поставить скобки в обратном слэше, чтобы сделать их в кадрах:

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

expr возвращает ошибку, если регулярное выражение не совпадает, поэтому вы можете использовать условную оболочку для проверки:

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

или

if ! port=$(expr "$response" : "$reg"); then
  # Do something on failure
fi
0 голосов
/ 30 июня 2018

С /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 используется не регулярное выражение, а шаблоны подстановки имени файла оболочки. Следовательно, шаблон будет соответствовать только одной цифре и запускать фиктивные строки, такие как {"port":0xxx}.

Если строка ответа является документом JSON:

$ response='{"port":98989}'
$ printf '%s\n' "$response" | jq .port
98989
0 голосов
/ 30 июня 2018

Есть проблемы с 'и "при использовании [[регулярные выражения (иногда; не всегда)), поэтому я бы попробовал это вместо этого (что прекрасно работает для меня):

#!/bin/bash

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