You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化用于Plan-Server匹配检测的awk命令中server_name提取逻辑?

问题描述

现有data.txt数据内容如下:

+----------------------------+---------+-------------------+
| Hostname                   | Plan    | Server            |
+----------------------------+---------+-------------------+
| hostname1                  | B20C120 | R1SG7.myfqdn.com  |
| another-host-name          | B40G66  | R1DC8.myfqdn.com  |
| the-other-hostname-is-here | B180G22 | R1SG8.myfqdn.com  |
| last.mydomain.com          | B400C88 | R1DG10.myfqdn.com |
+----------------------------+---------+-------------------+

使用以下AWK命令检测Plan与Server的匹配性(Plan以B开头且包含C/G,Server在R1S/R1D后包含C/G,二者C/G不匹配则输出告警):

awk -F '|' 'NF>3 {
  match($3, "B[0-9]{1,3}([CG])[0-9]{1,9}", plan);
  match($4, "R[0-9]{1,2}[DS]([CG])[0-9]{1,3}\.myfqdn\.com", server);
  match($2, "[a-zA-Z0-9 -.]{1,99}", server_name);
  if (plan[1] != server[1])
    print "wrong server ==> plan:", plan[0] ",", "server:", server[0], ", server_name:" server_name[0]
}' data.txt

当前输出符合预期:

wrong server ==> plan: B20C120, server: R1SG7.myfqdn.com, server_name: hostname1
wrong server ==> plan: B40G66, server: R1DC8.myfqdn.com, server_name: another-host-name
wrong server ==> plan: B400C88, server: R1DG10.myfqdn.com, server_name: last.mydomain.com

但提取server_name时需要编写复杂正则,尝试简化时遇到问题:

  • 使用match($2, server_name);报错:
awk: cmd. line:6: (FILENAME=data.txt FNR=4) fatal: attempt to use scalar `server_name' as an array
  • 使用match($2, "(.*)", server_name);输出无变化,期望优化server_name的提取方式,无需复杂正则。
解决方案

方法1:用gsub去除字段前后空格

$2是被|分隔的字段,仅前后存在多余空白字符,直接清理即可得到纯净的Hostname:

awk -F '|' 'NF>3 {
  match($3, "B[0-9]{1,3}([CG])[0-9]{1,9}", plan);
  match($4, "R[0-9]{1,2}[DS]([CG])[0-9]{1,3}\.myfqdn\.com", server);
  server_name = $2;
  gsub(/^[[:space:]]+|[[:space:]]+$/, "", server_name); # 清除前后所有空白字符
  if (plan[1] != server[1])
    print "wrong server ==> plan:", plan[0] ",", "server:", server[0], ", server_name:", server_name
}' data.txt

方法2:使用GNU AWK内置trim函数

如果使用的是GNU AWK(gawk),可以直接调用内置trim函数去除字符串前后空格:

awk -F '|' 'NF>3 {
  match($3, "B[0-9]{1,3}([CG])[0-9]{1,9}", plan);
  match($4, "R[0-9]{1,2}[DS]([CG])[0-9]{1,3}\.myfqdn\.com", server);
  server_name = trim($2);
  if (plan[1] != server[1])
    print "wrong server ==> plan:", plan[0] ",", "server:", server[0], ", server_name:", server_name
}' data.txt

方法3:简化match正则

如果坚持用match,可以用更简洁的正则匹配连续非空白字符(Hostname字段的有效内容就是中间的非空白序列):

awk -F '|' 'NF>3 {
  match($3, "B[0-9]{1,3}([CG])[0-9]{1,9}", plan);
  match($4, "R[0-9]{1,2}[DS]([CG])[0-9]{1,3}\.myfqdn\.com", server);
  match($2, "[^[:space:]]+", server_name); # 匹配第一个连续非空白字符序列
  if (plan[1] != server[1])
    print "wrong server ==> plan:", plan[0] ",", "server:", server[0], ", server_name:", server_name[0]
}' data.txt

以上三种方法都能避免编写复杂的字符集正则,高效提取到纯净的Hostname内容。


内容的提问来源于stack exchange,提问作者Saeed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 18:54:59