我需要根据CentOS服务器上的收集器名称从xml文件中提取所有FCP名称
CPM标签内的行数未知
最好是猛击,但任何解决方案都可以。
示例:输入文件
<CPM display_name="XYZ" collector="202a" >
<FCP name="a1" second_name="b2"/>
<FCP name="a3" second_name="b232323"/>
<FCP name="a2" second_name="b445"/>
</CMP>
<CPM display_name="XYZ" collector="204a" >
<FCP name="z1" second_name="b232323232"/>
<FCP name="s3" second_name="b23232323"/>
<FCP name="t2" second_name="b4453223"/>
</CMP>
<CPM display_name="XYZ" collector="202a" >
<FCP name="a11" second_name="basdasdasdasd2"/>
</CMP>
....
超过500行的长文件。
预期产量
collector="202a"
name="a1"
name="a2"
name="a3"
name="a11"
collector="204a"
name="z1"
name="s3"
name="t2
"
感谢您的帮助。
最佳答案
一个gawk
解决方案,使用match
、substr
、RSTART
和RLENGTH
可以模拟grep -o
行为和A[length(A)+1]=N
模拟阵列推送行为:
awk '
match($0, /collector="[^"]*"/){
collector=substr($0, RSTART, RLENGTH)
}
match($0,/[ ]name="[^"]*"/) {
d[collector][length(d[collector])+1]=substr($0, RSTART+1, RLENGTH)
}
END{
for(k in d){
print(k)
for (i in d[k]) print d[k][i]
print ""
}
}' file
编辑:谢谢,埃德·莫顿
awk '
match($0, /\<collector="[^"]*"/, a){ collector=a[0] }
match($0, /\<name="[^"]*"/, a){ d[collector][length(d[collector])+1]=a[0] }
END{
for(k in d){
print(k)
for (i in d[k]) print d[k][i]
print ""
}
}' file
你得到了,
collector="202a"
name="a1"
name="a3"
name="a2"
name="a11"
collector="204a"
name="z1"
name="s3"
name="t2"
附加:非
gawk
解决方案,sed
,grep
,sort
和tr
功能grep -oE '\b(collector|name)="[^"]*"' file |
sed ':a;N;$!ba;s/\nname/ name/g' |
sort -k1 |
sed ':a;$!N;/^\([^ ]*[ ]\).*\n\1/s/\n/ /;ta;P;D' |
sed 's/[ ]collector="[^"]*"//g' |
tr ' ' '\n'
你得到了,
collector="202a"
name="a11"
name="a1"
name="a3"
name="a2"
collector="204a"
name="z1"
name="s3"
name="t2"