多行模式匹配和删除行 - sed/awk/grep

多行模式匹配和删除行 - sed/awk/grep

输入.txt

-------
Database alias = ABC
Node name = node01
Hostname = hostnode01
Service name = 12345
-------
Hostname    = hostnode01
Service name    = 12345
-------
Database alias  = PQR
Node name   = node01
Hostname    = hostnode01
Service name    = 12345
-------
Hostname    = hostnode01
Service name    = 12345
-------
Database alias  = XYZ ......

预期输出

-------
Database alias  = ABC
Node name   = node01
Hostname    = hostnode01
Service name    = 12345
-------
Database alias  = PQR
Node name   = node01
Hostname    = hostnode01
Service name    = 12345
-------
Database alias  = XYZ ......

想法是删除主机名和服务名称的重复值(如果重复),或者'-------如果中间有 2 行,您可以说删除 ' 之间的行。

尝试使用 sed 进行多重匹配,但没有得到所需的 o/p

sed '/-------/{$!N;/\n.*Hostname/d;}' Input.txt

答案1

GNUawk方法:

awk 'BEGIN{ 
         RS = ORS = "-------\n";
         pat = "^Hostname += ([^ ]+)\nService name += ([^ ]+)\n$";  
     }
     NR == FNR{ 
         if (match($0, pat, a)) { items[a[1], a[2]]++ } 
         next 
     }
     match($0, pat, a) && (a[1], a[2]) in items \
     && items[a[1], a[2]] > 1{ next }1' inout.txt input.txt

输出:

-------
Database alias = ABC
Node name = node01
Hostname = hostnode01
Service name = 12345
-------
Database alias  = PQR
Node name   = node01
Hostname    = hostnode01
Service name    = 12345
-------
Database alias  = XYZ ......
-------

答案2

这不是一项工作sed(您不应该依赖连续的重复条目)。使用awk

  1. 将记录分隔符设置为正则表达式^-+$

  2. 使用关联数组,其中索引是主机名和服务名的串联。对于读取的任何记录,仅当该记录尚不存在时才将其放入数组中。

  3. 在处理文件结束时,打印出数组的所有元素,并使用----分隔符行格式化为单独的行。

答案3

也许您的示例数据集的简单性并不典型的实际用例,但考虑到您发布的示例的琐碎性,grep仅此就足够了:

$ grep --no-group-separator -A4 '^Database alias' input.txt 
Database alias = ABC
Node name = node01
Hostname = hostnode01
Service name = 12345
-------
Database alias  = PQR
Node name   = node01
Hostname    = hostnode01
Service name    = 12345
-------
Database alias  = XYZ ......

相关内容