regex - 仅打印配置文件中特定部分的行

标签 regex bash awk sed pcre

我的配置文件有很多部分。我需要收集特定部分的所有行。该部分可能会在一个文件中出现多次。 例如:

serviceA:
   ports:
     8080
     1323
serviceB:
  test:
      MMMM
  ports:
     8081
     3123
  network:
    ddddd

我读了这篇文章https://www.shellhacks.com/sed-awk-print-lines-between-two-patterns/并开始。

部分开头的模式很简单,它是 /ports:/ 但部分结尾的模式并不那么简单,它可以是任何名称,例如 [a- zA-Z]+:

我尝试在 awk 和 sed 中使用模式 [a-zA-Z]+:

在 awk 中。它只打印部分的名称

awk '/ports:/,/[a-zA-Z]+:/' file
    ports:
    ports:

在 sed 中。它从第一个端口打印到文件末尾

sed -n '/ports:/,/[a-zA-Z]+:/p' file
ports:
         8080
         1323
    serviceB:
      test:
         MMMM
      ports:
         8081
         3123
      network:
        ddddd

我认为问题在于模式 [a-zA-Z]+: 与 ports: 匹配,并决定排除 ports:。 ^\s*((?!ports)[a-zA-Z]+:)+ 此模式在在线正则表达式测试器中工作正常 - https://regex101.com/

awk 从第一个端口打印到文件末尾

awk '/ports:/,/^\s*((?!ports)[a-zA-Z]+:)+/' file
ports:
             8080
             1323
        serviceB:
          test:
             MMMM
          ports:
             8081
             3123
          network:
            ddddd

目前我只发现1个案例

awk '/ports:/,/network:|serviceB:/' 
  ports:
      8080
      1323
serviceB:
  ports:
      8081
      3123
network:

但是,我不知道节的所有可能名称。 我需要一个通用的解决方案。

最佳答案

根据您的数据格式,类似的内容应该有效

$ awk '/^[^ ]/{s=$0} /:/{p=0} /ports:/{print s; p=1} p' file

serviceA:
   ports:
     8080
     1323
serviceB:
  ports:
     8081
     3123

捕获服务名称,如果端口:与打印服务名称和部分匹配,则在下一个小节或部分重置打印标志p

如果您不需要部分名称

$ awk '/:/{p=0} p; /ports:/{p=1}' file

     8080
     1323
     8081
     3123

关于regex - 仅打印配置文件中特定部分的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53125660/

相关文章:

检查 C 中的空行 - 正则表达式

linux - 在 bash 中操作字符串

regex - 删除 awk 命令中的引号

bash - 使用grep获取文件中某个字符串第一次出现的行号

java - 为什么方括号内的点不匹配任何字符?

java - 如何在 Pattern.compile() 中转义管道字符

objective-c - Cocoa 中这个简单的正则表达式有什么问题

linux - 如何grep特定时间段内的日志文件

bash - 为什么: prevent ${username =`whoami` } from throwing an error?

linux - 在 bash/shell 中的关键字后添加文本