【发布时间】: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。两个版本都不错。正如我所见,解决方案是您必须首先为该部分的末尾设置正则表达式,然后为它的开头设置正则表达式