regex - 仅打印特定部分的配置文件中的行
问题描述
我有很多部分的配置文件。我需要从特定部分收集所有行。该部分可能在一个文件中出现多次。例如:
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]+:
我尝试[a-zA-Z]+:
在 awk 和 sed 中使用模式。
在 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:
但是,我不知道所有可能的部分名称。我需要一个通用的解决方案。
解决方案
根据您的数据格式,这样的东西应该可以工作
$ 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
推荐阅读
- python - Django:我可以在自定义命令中使用带有 docker-compose 的子进程吗?
- asp.net-web-api - AutoMapperMappingException:缺少类型映射配置或不支持的映射。[.NET 核心 3.1]
- amazon-web-services - 仅在一台服务器上运行 Ansible 任务 - AWS
- owasp - 禁用owasp依赖检查maven插件中的模块
- flutter - vscode定位flutter和dart sdk后显示错误
- blazor - 使用 Blazor Fluxor 进行状态管理
- c++ - 模板类中非模板成员函数的 requires 子句
- r - 在 dockerfile 中运行时,“install.packages(RODBC_1.2-6.tar.gz”中出现意外符号
- python - 使用 __setattr__ 和 __getattr__ 与 __slots__ 进行委托而不触发无限递归
- excel - 查找字符串范围内的最大值