首页 > 解决方案 > 将返回的 ip 和名称服务器过滤到字典中。重击

问题描述

我有一个像这样的文件:Example1:

haproxy-1
google_b 127.0.0.1
haproxy-2
google_b 127.0.0.1
haproxy-3
google_b 127.0.0.2

该文件可能有多个 ips 值,如下所示: Example2:

haproxy-1
google_b 127.0.0.1
google_b 127.0.0.2
haproxy-2
google_b 127.0.0.1
google_b 127.0.0.2
haproxy-3
google_b 127.0.0.1
google_b 127.0.0.2

我可以通过的唯一变量是 google_b 变量。Ips 和名称服务器是未知的,但可以通过 awk 正则表达式进行排序。我的目标是获取服务器返回的每个 ip 并将其放入字典中。

字典键需要是返回的 IP(如果是多个 ip,则为多个 ip)。字典值需要是返回该答案的服务器。

一般来说,我希望字典看起来像这样:

例如1:

haproxy_results=( ["127.0.0.1"]="haproxy-1 haproxy-2" ["127.0.0.2"]="haproxy-3")

例如2:

haproxy_results=( ["127.0.0.1"]="haproxy-1 haproxy-2 haproxy-3" ["127.0.0.2"]="haproxy-1 haproxy-2 haproxy-3")

示例 3:

haproxy-3
google_b 127.0.0.1
google_b 127.0.0.2
haproxy-4
Can't find backend

我现在如何做到这一点是我分别获取每个服务器的值,格式化它们以获取返回的 ips 和服务器,然后将其添加到字典中,如下所示:

haproxy-server 是haproxy-1haproxy-2等...

haproxy_ip_returned 是 ips127.0.0.1 127.0.0.2等...

haproxy_results+=([$haproxy_ip_returned]+=$haproxy-server)

这很糟糕,因为我使用 ansible 来获取数据并 ssh 到每个服务器分别导致代码非常慢。

关于如何做到这一点的任何想法?

标签: bashdictionaryawkformat

解决方案


$ eval declare -A haproxy_results=( $(
    awk -v tgt='google_b' '
        NF == 1 {
            srvr = $0
        }
        (NF == 2) && ($1 == tgt) {
            srvrs[$2] = ($2 in srvrs ? srvrs[$2] OFS : "") srvr
        }
        END {
            for (ip in srvrs) {
                printf "%s[\"%s\"]=\"%s\"", sep, ip, srvrs[ip]
                sep = OFS
            }
            print ""
        }
    ' file
) )

$ declare -p haproxy_results
declare -A haproxy_results=([127.0.0.2]="haproxy-1 haproxy-2 haproxy-3" [127.0.0.1]="haproxy-1 haproxy-2 haproxy-3" )

警告:使用eval会将文件的内容暴露给 shell 以进行解释,因此输入中的变量$PWD和命令等$(ls)将被扩展,因此只有在您确定输入中不会出现此类构造时才使用它。你可以做的更稳健但效率略低:

$ declare -A haproxy_results

$ while read -r ip srvrs; do
    haproxy_results["$ip"]="$srvrs"
done < <(
    awk -v tgt='google_b' '
        NF == 1 {
            srvr = $0
        }
        (NF == 2) && ($1 == tgt) {
            srvrs[$2] = ($2 in srvrs ? srvrs[$2] OFS : "") srvr
        }
        END {
            for (ip in srvrs) {
                print ip, srvrs[ip]
            }
        }
    ' file
)

$ declare -p haproxy_results
declare -A haproxy_results=([127.0.0.2]="haproxy-1 haproxy-2 haproxy-3" [127.0.0.1]="haproxy-1 haproxy-2 haproxy-3" )

以上假设在您的真实数据中,您的输入 IP 地址不以 google_b 开头,并且您想忽略这些。如果不是这种情况,那么摆脱-v tgt='google_b'and && ($1 == tgt)


推荐阅读