我们有以下包含主机名和主机 IP 的文件(长文件,每台 Linux 机器有 90-100 台机器)
hosts.cluster.conf
"href" : "http://localhost:8080/api/v1/hosts/worker02.sys87.com",
"Hosts" :
"cluster_name" : "hdp",
"host_name" : "worker02.sys87.com",
"ip" : "23.67.32.65"
"href" : "http://localhost:8080/api/v1/hosts/worker03.sys87.com",
"Hosts" :
"cluster_name" : "hdp",
"host_name" : "worker03.sys87.com",
"ip" : "23.67.32.66"
"href" : "http://localhost:8080/api/v1/hosts/worker04.sys87.com",
"Hosts" :
"host_name" : "worker04.sys87.com",
"ip" : "23.67.32.67"
"href" : "http://localhost:8080/api/v1/hosts/worker05.sys87.com",
"Hosts" :
"cluster_name" : "hdp",
"host_name" : "worker05.sys87.com",
"ip" : "23.67.32.68"
我们想打印所有主机名仅当上一行之前包含“集群名称“ 单词
预期成绩
"host_name" : "worker02.sys87.com",
"host_name" : "worker03.sys87.com",
"host_name" : "worker05.sys87.com",
答案1
sed '/host_name/!h;//!d;x;/cluster_name/!d;g' infile
host_name
将保存与旧缓冲区不匹配的每一行h
,然后d
将其删除;对于每个剩余的行,它将x
更改缓冲区,如果模式空间不包含cluster_name
它将删除它,否则它将g
从保留缓冲区和自动打印中返回原始行。
答案2
尝试
awk '/cluster_name/ {p=1 ; next ;}
/host_name/ && p { print ; }
{p=0}'
这个基本上记住就行了cluster_name
。如果host_name
找到,cluster_name
之前没有,则不会打印。
请注意,整个 awk 代码可以是一行。
答案3
短的awk
解决方案:
awk '/cluster_name/{ cl=NR }/host_name/ && NR-1==cl' hosts.cluster.conf
/cluster_name/{ cl=NR }
- 捕获记录"cluster_name"
行数/host_name/
- 在相遇"host_name"
线上NR-1==cl
- 确保当前"host_name"
记录号NR
是"cluster_name"
记录号之后的下一个(由 表示cl
)
输出:
"host_name" : "worker02.sys87.com",
"host_name" : "worker03.sys87.com",
"host_name" : "worker05.sys87.com",
如果host_name
出现在第一行,尽管我对实际情况表示怀疑,请使用以下版本:
awk '/cluster_name/{ cl=NR }/host_name/ && cl && NR-1==cl' hosts.cluster.conf
答案4
好吧,我们已经有了sed
,awk
现在是 GNU 的时候了grep
!
cat infile | grep --after-context 1 cluster_name | grep host_name
解释
第一个命令cat
将数据读出到管道中进行处理。您可以将此段替换为将源文本输出到 的任何命令stdout
。
第二个命令查找其中包含“cluster_name”的任何行,并打印它和下一行。中间输出是这样的:
"cluster_name" : "hdp",
"host_name" : "worker02.sys87.com",
--
"cluster_name" : "hdp",
"host_name" : "worker03.sys87.com",
--
"cluster_name" : "hdp",
"host_name" : "worker05.sys87.com",
然后最后一段仅打印其中包含“host_name”的行的内容。因此最终的输出是:
"host_name" : "worker02.sys87.com",
"host_name" : "worker03.sys87.com",
"host_name" : "worker05.sys87.com",
评论
- 并不是每个人
grep
都有“--before-context parameter.
确保您使用的是 GNU grep”,并且应该没问题。 - 如果这是像 JSON 这样的语言,那么您最好学习和使用适合语言的解析器,例如 jmespath 或
jq
.