【问题标题】:Print lines from config files for specific section only仅打印特定部分的配置文件中的行
【发布时间】:2018-11-02 20:49:44
【问题描述】:

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

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]+: 与端口匹配:并决定排除端口:。 ^\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

目前我只找到一个案例

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

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

【问题讨论】:

  • 感谢@potong 和 karakfa。两个版本都不错。正如我所见,解决方案是您必须首先为该部分的末尾设置正则表达式,然后为它的开头设置正则表达式

标签: regex bash awk sed pcre


【解决方案1】:

根据您的数据格式,这样的东西应该可以工作

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

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

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

如果您不需要部分名称

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

     8080
     1323
     8081
     3123

【讨论】:

    【解决方案2】:

    这可能对你有用(GNU sed):

    sed '/:$/h;//d;G;/ports:$/P;d' file
    

    将每个部分名称存储在保留空间中,然后删除该行。对于其他每一行,附加最近的部分名称,如果恰好是 ports:,则仅打印当前行。

    【讨论】:

      【解决方案3】:

      您的输入是YAML,最好使用YAML 解析器来解析此数据。

      您可以使用此ruby 代码打印所有顶部部分中处于第二级的ports

      ruby -ryaml -e "data=YAML::load(STDIN.read); data.each{|n|puts n.last['ports']}" < file.yml
      

      8080 1323
      8081 3123
      

      【讨论】:

      • 感谢您的回答。但我想在没有新装置的情况下做出决定。我想使用标准的 Linux 工具
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-21
      • 2017-09-24
      • 2019-11-30
      • 2011-04-11
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      相关资源
      最近更新 更多