使用shell命令需要解析XML文件的多个嵌套标记值
我有这个XML文件-使用shell命令需要解析XML文件的多个嵌套标记值,xml,bash,shell,sed,awk,Xml,Bash,Shell,Sed,Awk,我有这个XML文件- <gp> <mms>1110012</mms> <tg>988</tg> <mm>LongTime</mm> <lv> <lkid>StartEle=ONE, Desti = Motion</lkid> <kk>12</kk> </lv> <lv> <lkid>StartE
<gp>
<mms>1110012</mms>
<tg>988</tg>
<mm>LongTime</mm>
<lv>
<lkid>StartEle=ONE, Desti = Motion</lkid>
<kk>12</kk>
</lv>
<lv>
<lkid>StartEle=ONE, Source = Velocity</lkid>
<kk>2</kk>
</lv>
<lv>
<lkid>StartEle=ONE, Source = Park</lkid>
<kk>2</kk>
</lv>
</gp>
<gp>
<mms>2221100</mms>
<tg>989</tg>
<mm>LongVelocity</mm>
<lv>
<lkid>StartEle=ONE, Source = Velocity</lkid>
<kk>772</kk>
</lv>
<lv>
<lkid>StartEle=ONE, Desti = Motion</lkid>
<kk>900</kk>
</lv>
<lv>
<lkid>StartEle=ONE, Source = Park</lkid>
<kk>2</kk>
</lv>
</gp>
1110012
988
长期
星光=一,目标=运动
12
星电视=一,震源=速度
2.
StartEle=1,震源=Park
2.
2221100
989
长速度
星电视=一,震源=速度
772
星光=一,目标=运动
900
StartEle=1,震源=Park
2.
现在,我需要首先搜索“LongTime”,如果找到了,那么我必须在多个嵌套子标记中查找“Desti=Motion”值(在StartEle=ONE,Desti=Motion中)。。。如果也找到了,那么我最后必须得到下面标记中的值,即12(12)
请帮助,使用任何东西-AWK、SED、Grep,任何东西都可以
提前感谢。使用awk
awk -F"[<>]" '/LongTime/ {f=1} f && /Desti = Motion/ {getline;print $3;f=0}' file
12
要避免使用
getline
以防出现额外的空行,请使用以下命令:
awk -F"[<>]" '/LongTime/ {f=1} /^<mm>/ && !/LongTime/ {f=0} f && /Desti = Motion/ {q=1} f && q && /<kk>/ {print $3;f=q=0}' file
12
awk-F“[]”/LongTime/{F=1}/^/&/LongTime/{f=0}f&&/Desti=Motion/{q=1}f&&q&/{print$3;f=q=0}文件
12
只需添加一个额外的测试
以下是一些更具可读性的:
awk -F"[<>]" '
/LongTime/ {f=1}
/^<mm>/ && !/LongTime/ {f=0}
f && /Desti = Motion/ {q=1}
f && q && /<kk>/ {print $3;f=q=0}
' file
awk-F“[]”
/长时间/{f=1}
/^/ && !/长时间/{f=0}
f&&/Desti=Motion/{q=1}
f&&q&&/{print$3;f=q=0}
"档案"
sed-n'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\{
\|Desti=运动|,\|{
//s |]*>| gp
}
}“你的档案
这对您的示例XML有用,但如果它(在格式上)发生了更改,请指定您期望的更改类型(新行的情况在这里是可以的)[使用-posix for GNU-sed]在GNU Awk版本4中,您可以尝试以下操作:
gawk -f a.awk file.xml
其中a.awk
为:
BEGIN {
RS="^$"
FPAT="(<mm>LongTime</mm>)|(<lkid>[^<]*</lkid>)|(<kk>[^<]*</kk>)"
}
{
do {
if ($(++i)=="<mm>LongTime</mm>") {
do {
if ($(++i)~/<lkid>.*Desti = Motion.*<\/lkid>/) {
match ($(i+1),/<kk>([^<]*)<\/kk>/,a)
print a[1]
exit
}
} while (i<=NF)
}
} while (i<=NF)
}
开始{
RS=“^$”
FPAT=“(LongTime)|”([^试着看看这个答案:当我解析XML流时,我更喜欢使用经过优化的工具。有许多shell语言和命令支持DOM方法、Xpath查询等。比如Perl(由大多数Linux发行版提供)、Python、PHP(有一个PHP解释器,它允许我们用PHP编写一些shell脚本)、xmllint等等。但是如果在上面和下面的标记之间有一个新行,例如-StartEle=ONE,Desti=Motion----新行--12,我可以添加2“getline;“要解决它,我知道有一个新行,但这必须是动态的,因为其他一些这样的标签可能有临时空格/新行,这是事先不知道的。请提供您的输入。
gawk -f a.awk file.xml
BEGIN {
RS="^$"
FPAT="(<mm>LongTime</mm>)|(<lkid>[^<]*</lkid>)|(<kk>[^<]*</kk>)"
}
{
do {
if ($(++i)=="<mm>LongTime</mm>") {
do {
if ($(++i)~/<lkid>.*Desti = Motion.*<\/lkid>/) {
match ($(i+1),/<kk>([^<]*)<\/kk>/,a)
print a[1]
exit
}
} while (i<=NF)
}
} while (i<=NF)
}