bash - 将返回的 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-1
或haproxy-2
等...
haproxy_ip_returned 是 ips127.0.0.1
127.0.0.2
等...
haproxy_results+=([$haproxy_ip_returned]+=$haproxy-server)
这很糟糕,因为我使用 ansible 来获取数据并 ssh 到每个服务器分别导致代码非常慢。
关于如何做到这一点的任何想法?
解决方案
$ 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)
。
推荐阅读
- sql-server - 在 T-SQL 中对最多 2 列进行子查询的最佳方法是什么
- typo3 - 为来自 CLI 的图像生成 TYPO3 cropVariants
- python - 如何单击使用 Selenium 隐藏的下拉菜单?
- sql - 从逗号分隔的字符串中提取字符串的 SQL 查询
- python - 如何从列表中删除元素列表?
- postgresql - hasura:将空字符串视为空值
- reactjs - 使用 redux 在 next.js 中管理状态
- vuetify.js - 如何在 Vuetify v-select 中使用对象?
- php - 缺少 MySQLi 扩展
- amazon-web-services - 将标签添加到批处理作业并在 Cost Explorer 中查看它们