AWK循环中变量值替换失效:计划名称替换需求及排障
解决AWK脚本中计划名称替换失效问题
文件内容
fileA内容
+--------------------+-----------+------------+-----------+------------+ | Name | Status | Networks | Image | Plans | +--------------------+-----------+------------+-----------+------------+ | HostName A | PAUSED | IP=1.1.1.1 | Ubuntu20 | Plan BGP40 | | An other hostname | ACTIVE | IP=2.2.2.2 | Ubuntu20 | Plan BGP30 | | final.destination | REBOOTING | IP=3.3.3.3 | Debian11 | Plan BGP10 | | no problem | ACTIVE | IP=4.4.4.4 | Centos7 | Plan BGP90 | | no problem | ACTIVE | IP=6.6.6.6 | Ubuntu22 | Plan BGP60 | +--------------------+-----------+------------+-----------+------------+
fileB内容
dedicated_ip: 1.1.1.1 name: 'AIPlan BGP40' dedicated_ip: 2.2.2.2 name: 'IAPlan BGP30' dedicated_ip: 3.3.3.3 name: 'Plan BGP10' dedicated_ip: 4.4.4.4 name: 'Plan BGP90' dedicated_ip: 5.5.5.5 name: 'Plan BGP20' dedicated_ip: 6.6.6.6 name: 'PVPlan BGP100'
需求逻辑
- 若主机名为
serverA或serverB,需将AIPlan和IAPlan替换为Plan - 若主机名为
serverC或serverD,需将PVPlan替换为Plan
原脚本问题分析
- gsub使用错误:
ip=gsub(/AIPlan/,"Plan")将gsub返回的替换次数赋值给了ip变量,而非修改计划名字符串,且未作用在目标变量c[2]上 - 未覆盖所有替换规则:未处理
IAPlan的替换需求 - 条件逻辑错误:
c[2] == plans[ip]的判断不符合实际场景——fileB中的计划名是待替换的原始值,与fileA中的目标值不匹配,导致部分替换逻辑未触发 - 代码块语法问题:if语句块未用大括号包裹,导致仅第一行代码执行
修正后的AWK脚本
awk -v qt="'" -v host="${HOSTNAME,,}" ' # 处理fileA,构建IP到目标计划名的映射 FNR==NR { if (FNR >= 4 && !/-------/) { # 跳过表头和分隔线 split($0, a, "[[:blank:]]*[|][[:blank:]]*") split(a[4], b, "=") ip = b[2] plans[ip] = a[6] # 存储IP对应的最终计划名 } next } # 处理fileB,提取IP和计划名 /dedicated_ip:/ { current_ip = $2 next } /name:/ { split($0, c, qt) current_plan = c[2] modified_plan = current_plan # 根据主机名执行对应替换规则 if (host ~ /^(serverA|serverB|desktop-9pr0r3p)$/) { gsub(/(AIPlan|IAPlan)/, "Plan", modified_plan) } else if (host ~ /^(hostnamec.my.domain.com|hostnamed.my.domain.com)$/) { gsub(/PVPlan/, "Plan", modified_plan) } # 仅输出fileA中存在的IP对应的内容 if (current_ip in plans) { printf "%s == %s\n%s == %s\n", current_ip, current_ip, modified_plan, plans[current_ip] } } ' fileA fileB
修正点说明
- 调整gsub的作用对象:直接在计划名字符串上执行替换,得到修改后的值
- 扩展替换规则:用正则
/(AIPlan|IAPlan)/一次性匹配两种需要替换的前缀 - 优化判断逻辑:只要IP存在于fileA的映射中就输出,确保所有目标IP都被处理
- 修复语法问题:用大括号包裹if语句块,保证代码块内所有语句执行
- 变量命名规范化:使用
current_ip、modified_plan等清晰命名,提升代码可读性
预期输出
当主机名为serverA时,输出如下:
1.1.1.1 == 1.1.1.1 Plan BGP40 == Plan BGP40 2.2.2.2 == 2.2.2.2 Plan BGP30 == Plan BGP30 3.3.3.3 == 3.3.3.3 Plan BGP10 == Plan BGP10 4.4.4.4 == 4.4.4.4 Plan BGP90 == Plan BGP90
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

