Регулярное выражение для извлечения строки из текста многострочного файла - PullRequest
1 голос
/ 19 февраля 2020

Я ищу способ извлечь IP-адрес партнера, ища секрет этого партнера.

Пример:

peer 1.2.3.10 {
    authentication {
        mode pre-shared-secret
        pre-shared-secret SecretPasswordA
    }
    connection-type initiate
    ike-group IKE_1.2.3.4
    local-address 6.7.8.9
    vti {
        bind vti64
        esp-group ESP_1.2.3.4
    }
}
peer 1.2.3.20 {
    authentication {
        mode pre-shared-secret
        pre-shared-secret SecretPasswordB
    }
    connection-type initiate
    ike-group IKE_1.2.3.4
    local-address 6.7.8.9
    vti {
        bind vti64
        esp-group ESP_1.2.3.4
    }
}
peer 1.2.3.30 {
    authentication {
        mode pre-shared-secret
        pre-shared-secret SecretPasswordC
    }
    connection-type initiate
    ike-group IKE_1.2.3.4
    local-address 6.7.8.9
    vti {
        bind vti64
        esp-group ESP_1.2.3.4
    }
}

При условии, что я знаю SecrePasswordB, мне нужно получить IP-адрес равный 1.2.3.20, пустой, если не найден (или что-либо еще, что легко идентифицировать.

Текст приходит из команды оболочки в переменную (ie. TEXT=$(command_string)).

Поскольку у меня есть только базовая c оболочка и несколько инструментов, доступных в системе, что нужно было бы сделать с очень базовыми c linux инструментами. И здесь я застрял, не найдя решения ...

Ответы [ 2 ]

2 голосов
/ 19 февраля 2020

Если у вас есть переменная TEXT, назначенная целым строкам, приведенным в качестве примера, попробуйте:

secret="SecretPasswordB"        # or assign to your actual string
secret=$(printf %q "$secret")   # escape metacharacters just in case

pat='peer[[:blank:]]+(([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3})[[:blank:]]*\{[^{]+authentication[[:blank:]]*\{[^}]+pre-shared-secret[[:blank:]]+'"$secret"

if [[ $TEXT =~ $pat ]]; then
    echo "${BASH_REMATCH[1]}"
fi

Вывод:

1.2.3.20

Обратите внимание, что Приведенное выше регулярное выражение проверено только на данном примере и может быть недостаточно надежным для произвольного ввода.

1 голос
/ 19 февраля 2020

Если данные отформатированы в отдельные строки, как показано в вопросе, тогда достаточно простого сценария оболочки. Просто разделите ввод на ведущее слово, а затем на остальное. Сохраняйте IP всякий раз, когда читается «равноправная» строка. Напечатайте самый последний IP-адрес, если секрет прочитан.

getPeerIP :

#!/bin/sh

secret="$1"

while read -r arg1 rest; do
    case "$arg1" in
        peer)
            ip="${rest% *}" # prune everything after first space
            ;;
        pre-shared-secret)
            if [ "$rest" = "$secret" ]; then
                echo "$ip"
                exit # don't bother reading rest of file
            fi
            ;;
    esac
done

Использование:

command_string | getPeerIP 'Secret Password'
...