使用grep(或sed或awk)命令来选择文件中特定起始行之后的特定模式后面的所有行 [英] A grep (or sed, or awk) command to select all lines that follow a specific pattern after a specific start line in a file
问题描述
在 Docker Compose
的 yml
文件中,卷是在以 volumes:
行,后面跟着诸如 - host / dir:guest:dir
之类的模式。该节以下一节的开始处结束,其名称将始终不相同,它可以是端口中的任何一个:
,环境:
和网络:
等等。通常有多个卷:
部分,并且每个部分中的行数不知道(并且在卷之间不是恒定的:
部分)。
我需要从所有的音量声明中提取所有音量声明(即 - host / dir:guest:dir
) 卷:
谢谢!
例子 yml
档案:
版本:'2'
服务:
service1:
图片:repo1 / image1
卷:
- / dir1 / dir2: / dir3 / dir4
- / dir5 / dir6:/ dir7 / dir8
端口:
- 80:80
服务2:
图片:repo2 / image2
卷:
- / dir9 / dir10:/ dir11 / dir12
环境:
- A:B
awk 一行代码 b
$ b
在每个批量声明中都有 /
输入:
版本:'2'
服务:
服务1:
图片:repo1 / image1
卷:
- / dir1 / dir2:/ dir3 / d ir4
- / dir5 / dir6:/ dir7 / dir8
端口:
- 80:80
服务2:
图片:repo2 / image2
卷:
- / dir9 / dir10:/ dir11 / dir12
环境:
- A:B
卷:
- / dir1 / dir2:/ dir3 / dir4
- / dir5 / dir6:/ dir7 / dir8
meow:
输出:
$ awk'$ 0!〜/{a = 0} / volumes:/ {A = 1;下一个} a'文件
- / dir1 / dir2:/ dir3 / dir4
- / dir5 / dir6:/ dir7 / dir8
- / dir9 / dir10:/ dir11 / dir12
- / dir1 / dir2:/ dir3 / dir4
- / dir5 / dir6:/ dir7 / dir8
$ 0!〜/{a = 0}
:如果记录/行不包含 / $ c $这意味着它不是卷的声明;设置
a = 0
/ volumes:/ {a = 1;下一步}
:如果该行包含卷:
,则设置 a = 1
和 next
即跳到下一条记录
a
:打印记录if a = 1
PS:如果在你的yml文件中包含 /
的标签可以在卷之后,这可能会失败。如果是这样的话,请使用awk:
$ $ p $ $ $ $!$ $ $!$〜{a = 0} /卷: / {A = 1;下一个} a'文件
这会重置 a
如果第一个字段不是 -
In the yml
files of Docker Compose
, the volumes are declared in a section that starts with volumes:
line and followed by patterns such as - host/dir:guest:dir
. The sesction ends with the start of the next section, which its name would not be the same all the time, and it could be any of ports:
, environment:
, and networks:
, among others. There is usually more than one volumes:
section, and the number of lines in each of those is not known (and is not constant across the volumes:
sections).
I need to extract all the volume declarations (i.e., - host/dir:guest:dir
) from all volumes:
sections of a yml
file.
Thanks!
An example yml
file:
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
awk one-liner
Assuming you have /
in each volume declaration
Input :
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:
Output:
$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}
: If the record/line doesn't contain /
that means it's not a volume declaration ; set a=0
/volumes:/{a=1; next}
: If the line contains volumes:
then set a=1
and next
i.e jump to next record
a
: To print the records if a=1
PS : If in your yml file a tag containing /
can come just after volumes then this can fail. If that's the case then use this awk :
$awk '$1!~"-"{a=0} /volumes:/{a=1; next}a' file
This will reset a
if first field isn't -
这篇关于使用grep(或sed或awk)命令来选择文件中特定起始行之后的特定模式后面的所有行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!