grep(或sed或awk)命令,用于选择文件中特定起始行后面的特定模式后面的所有行

问题描述 投票:-2回答:2

ymlDocker Compose文件中,卷在一个以volumes:线开头的部分中声明,然后是- host/dir:guest:dir之类的模式。该部分以下一部分的开头结束,其名称不会始终相同,并且可以是ports:environment:networks:等中的任何一个。通常有不止一个volumes:部分,并且每个部分中的行数是未知的(并且在volumes:部分不是恒定的)。

我需要从- host/dir:guest:dir文件的所有volumes:部分提取所有的声明声明(即yml)。

谢谢!

一个示例yml文件:

version: '2'
services:
  service1:
    image: repo1/image1
    volumes:
      - /dir1/dir2:/dir3/dir4
      - /dir5/dir6:/dir7/dir8
    ports:
      - "80:80"
  service2:
    image: repo2/image2
    volumes:
      - /dir9/dir10:/dir11/dir12
    environment:
      - A: B
bash awk sed grep yaml
2个回答
1
投票

awk one-liner

假设你在每个卷声明中都有/

输入:

version: '2'
services:
  service1:
    image: repo1/image1
    volumes:
      - /dir1/dir2:/dir3/dir4
      - /dir5/dir6:/dir7/dir8
    ports:
      - "80:80"
  service2:
    image: repo2/image2
    volumes:
      - /dir9/dir10:/dir11/dir12
    environment:
      - A: B
    volumes:
      - /dir1/dir2:/dir3/dir4
      - /dir5/dir6:/dir7/dir8
meow:

输出:

$awk '$0!~"/"{a=0}  /volumes:/{a=1; next}a' file
      - /dir1/dir2:/dir3/dir4
      - /dir5/dir6:/dir7/dir8
      - /dir9/dir10:/dir11/dir12
      - /dir1/dir2:/dir3/dir4
      - /dir5/dir6:/dir7/dir8

$0!~"/"{a=0}:如果记录/行不包含/,则表示它不是卷声明;设置a=0 /volumes:/{a=1; next}:如果该行包含volumes:然后设置a=1next,即跳转到下一条记录 a:如果a=1打印记录

PS:如果你的yml文件中包含/的标签可以在卷之后出现,那么这可能会失败。如果是这种情况,那么使用这个awk:

$awk '$1!~"-"{a=0}  /volumes:/{a=1; next}a' file

如果第一个字段不是a,这将重置-


1
投票
awk '$1=="-"{if (f) print; next} {f=/^[[:space:]]*volumes:/}' file
© www.soinside.com 2019 - 2024. All rights reserved.