如何用awk逐行正则匹配校验Plan Name与Server Zone对应关系
问题描述
需要用awk处理以下服务器清单文本,逐行校验每行的Plan Name与Server Zone是否匹配,仅校验当前行:
+--------------------------------------+------------------+---------+------------+-------------+------------------------------------------------------------------------+------------+--------------------------------------+----------------+--------------------------------------+-------------------+--------------------------+----------------------+ | ID | Name | Status | Task State | Power State | Networks | Image Name | Image ID | Plan Name | Plan ID | Server Zone | Host | Properties | +--------------------------------------+------------------+---------+------------+-------------+------------------------------------------------------------------------+------------+--------------------------------------+----------------+--------------------------------------+-------------------+--------------------------+----------------------+ | 7ddd34d7-f081-4228-8023-9f3e2c5c686c | some_hostname | ACTIVE | None | Running | External_Network=2.2.2.2; Internal_Network=10.10.10.3 | Ubuntu20 | 584f8dd7-2554-4215-8fc2-7c16ade9d5d6 | Plan A100C124 | 9511d8a1-dc84-4c6b-addc-328751c73d2f | Z1DG3.my-fqdn.com | Z1DG3.my-fqdn.com | some test properties | | dd39f9c4-7043-431d-aa97-a3a6b60286d7 | another hostname | ACTIVE | None | Running | External_Network=3.3.3.3 | Ubuntu20 | 584f8dd7-2554-4215-8fc2-7c16ade9d5d6 | Plan A200G84 | 9511d8a1-dc84-4c6b-addc-328751c73d2f | Z1DG3.my-fqdn.com | Z1DG3.my-fqdn.com | | | 005b5329-d506-4482-8d2c-54e429e90b56 | third server | ACTIVE | None | Running | External_Network=4.4.4.4; Internal_Network=10.10.10.106, 10.10.11.106 | Centos7 | 33b0b27d-daa6-44a4-ac04-96bbbf5f78f5 | Dlan A50C22 | b6a93f35-26e6-416b-9d46-bef6651b3011 | Z1DG2.my-fqdn.com | old-hostname.my-fqdn.com | admin notes | | 060fdefa-259b-4256-8781-98b535ec11c3 | last one | ACTIVE | None | Running | External_Network=5.5.5.5 | Debian 12 | b98de22d-03a9-4417-ac23-9026344ad74d | Plan A40G12 | 824a373c-01c4-439c-9576-f862a74069e5 | Z1DG2.my-fqdn.com | old-hostname.my-fqdn.com | | | be4f5a16-8817-489e-b250-a10e72ab3187 | 1.1.1.1 | PAUSED | None | Paused | External_Network=1.1.1.1 | RedHat 8 | 69289e81-2dd6-4dbf-af73-8187f8277fab | Vlan A250C2418 | 801de143-d172-4b38-b5bb-969dd1eb2289 | Z1SG3.my-fqdn.com | Z1SG3.my-fqdn.com | | +--------------------------------------+------------------+---------+------------+-------------+------------------------------------------------------------------------+------------+--------------------------------------+----------------+--------------------------------------+-------------------+--------------------------+----------------------+
校验规则
- Plan Name核心格式为
A[0-9]{1,3}[CG][0-9]{1,9},前缀可能是Plan、Vlan等任意内容 - Server Zone格式为
Z[0-9]{1,2}[DS][CG][0-9]{1,3}\.my-fqdn.com - 匹配逻辑:Plan Name中的
C/G字符必须与Server Zone中的CG部分一致,不匹配时输出指定格式的错误信息
预期输出
wrong server ==> ip 2.2.2.2, plan A100C124, server Z1DG3.my-fqdn.com wrong server ==> ip 4.4.4.4, plan A50C22, server Z1DG2.my-fqdn.com wrong server ==> ip 1.1.1.1, plan A250C2418, server Z1SG3.my-fqdn.com
解决方案
使用以下awk命令即可实现需求:
awk -F'|' ' # 跳过表头和分隔线 /^\+/ || /ID/ { next } { # 提取并清洗Plan Name字段 plan_name = $9 gsub(/^[[:space:]]+|[[:space:]]+$/, "", plan_name) # 提取并清洗Server Zone字段 server_zone = $11 gsub(/^[[:space:]]+|[[:space:]]+$/, "", server_zone) # 提取外部IP networks = $6 gsub(/^[[:space:]]+|[[:space:]]+$/, "", networks) split(networks, nets, /;/) ext_ip = "" for (n in nets) { if (nets[n] ~ /External_Network=/) { split(nets[n], ip_parts, /=/) ext_ip = ip_parts[2] break } } # 匹配Plan中的C/G字符 if (plan_name ~ /A[0-9]{1,3}([CG])[0-9]{1,9}/) { plan_cg = substr(plan_name, RSTART+length(RPRE)+1, 1) } else { next } # 匹配Server Zone中的C/G字符 if (server_zone ~ /Z[0-9]{1,2}[DS]([CG])[0-9]{1,3}\.my-fqdn\.com/) { zone_cg = substr(server_zone, RSTART+length(RPRE)+1, 1) } else { next } # 对比不匹配则输出错误信息 if (plan_cg != zone_cg) { match(plan_name, /A[0-9]{1,3}[CG][0-9]{1,9}/) plan_core = substr(plan_name, RSTART, RLENGTH) printf("wrong server ==> ip %s, plan %s, server %s\n", ext_ip, plan_core, server_zone) } } ' server_list.txt
命令解释
- 字段分隔:以
|作为分隔符拆分每行内容 - 跳过无关行:过滤掉以
+开头的分隔线和包含表头的行 - 字段清洗:去除
Plan Name、Server Zone、Networks字段的前后空格 - IP提取:从
Networks字段中解析出外部网络IP - 字符匹配:用正则分别提取Plan和Server Zone中的
C/G标识字符 - 对比输出:若两个字符不匹配,提取Plan核心部分并按指定格式输出错误信息
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

