从多行文件文本中检索字符串的正则表达式

Regular expression to retrieve a string from a multiline file text

我正在寻找一种通过查找对等方的秘密来提取对等方 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,我将需要检索 1.2.3.20 的对等 IP,如果找不到则为空(或其他任何容易识别的 IP。

文本来自 shell 命令到变量(即 TEXT=$(command_string))。

因为我只有一个基本的 shell 并且系统上可用的工具很少,需要使用非常基本的 linux 工具来完成。在这里我一直找不到解决方案...

假设您有一个变量 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

请注意,上面的正则表达式仅针对给定的示例进行了测试,对于任意输入可能不够稳健。

如果数据被格式化为单独的行,如问题所示,那么一个简单的 shell 脚本就足够了。只需将输入拆分为一个前导词,然后是其余词。每当读取 "peer" 行时保存 IP。如果秘密被读取,则打印最近的 IP。

getPeerIP:

#!/bin/sh

secret=""

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'