regex awk如何在匹配时打印整列

qv7cva1a  于 2023-11-20  发布在  其他
关注(0)|答案(2)|浏览(251)

这是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命令:

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


上述txtawk的逻辑为:
计划名称中包含C或G(在B之后,B始终是第一个字母),服务器名称在R1 S或R1 D之后包含C或G。
例如,如果计划是B20C120,服务器是R1SG7,那么由于C和G不匹配,因此它是错误的计划服务器。
但是B180G22在R1SG8中,这是正确的。
我当前的awk命令在我的脑海中有这个问题:

  1. server是打印出来的,但我必须写一个正则表达式。
    我在awk中尝试了这个:
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更好

omjgkv6w

omjgkv6w1#

使用您所展示的示例和尝试,请尝试遵循GNU awk代码。这种方法只使用一个单个数组,只捕获那些需要匹配的值。

  • 代码详解:*
  • match函数中使用正则表达式^\|[[:space:]]+([^[:space:]]+)[[:space:]]+\|[[:space:]](B[0-9]{1,3}([CG])[0-9]{1,9})[[:space:]]+\|[[:space:]]+(R[0-9]{1,2}[DS]([CG])[0-9]{1,3}\.myfqdn\.com)
  • 如果该行匹配为TRUE,则在该正则表达式中创建5个捕获组。
  • 这将所有捕获组值保存到名为values的数组中。
  • 数组的索引将从1到5开始,例如:values[1]用于第一个捕获组。
awk '
match($0,/^\|[[:space:]]+([^[:space:]]+)[[:space:]]+\|[[:space:]](B[0-9]{1,3}([CG])[0-9]{1,9})[[:space:]]+\|[[:space:]]+(R[0-9]{1,2}[DS]([CG])[0-9]{1,3}\.myfqdn\.com)/,values){
  if(values[3]!=values[5]){
     print "wrong server ==> plan: " values[2] " , server: " values[4] ", server_name: " values[1]
  }
}
'  Input_file

字符串

  • 或者 * 根据艾德先生的评论,在GNU awk中,[^[:space:]]可以简单地写为\S[[:space:]]可以简单地写为\s
awk '
match($0,/^\|\s+(\S+)\s+\|\s(B[0-9]{1,3}([CG])[0-9]{1,9})\s+\|\s+(R[0-9]{1,2}[DS]([CG])[0-9]{1,3}\.myfqdn\.com)/,values){
  if(values[3]!=values[5]){
     print "wrong server ==> plan: " values[2] " , server: " values[4] ", server_name: " values[1]
  }
}
'  Input_file


示例输出如下:

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

dffbzjpn

dffbzjpn2#

您可以使用此gnu awk解决方案:

cat parse.awk

BEGIN {
   FS = "\\s*[|]\\s*"
}
NF > 3 {
  server_name = $2
  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);
  if (plan[1] != server[1])
    print "wrong server ==> plan:", plan[0] ",", "server:", server[0] ", server_name:", server_name
}

字符串
然后将其用作:

awk -f parse.awk file

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

详情:

  • FS = "[[:blank:]]*\\|[[:blank:]]*"FS设置为|,两侧由可选空格包围
  • 使用正则表达式文字/.../而不是字符串作为正则表达式。
  • 为了更精确和正确的匹配,在正则表达式中使用了锚点^$
  • 现在有了正确的FS,我们不需要使用任何正则表达式来设置server_name,只需要$2赋值就足够了

要直接从bash命令行使用此命令,请使用:用途:

awk '
BEGIN {
   FS = "\\s*[|]\\s*"
}
NF>3 {
  server_name = $2
  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);
  if (plan[1] != server[1])
    print "wrong server ==> plan:", plan[0] ",", "server:", server[0] ", server_name:", server_name
}' file

相关问题