使用awk命令提取xml标记值

我有一个像下面的XML

<root> <FIToFICstmrDrctDbt> <GrpHdr> <MsgId>A</MsgId> <CreDtTm>2001-12-17T09:30:47</CreDtTm> <NbOfTxs>0</NbOfTxs> <TtlIntrBkSttlmAmt Ccy="EUR">0.0</TtlIntrBkSttlmAmt> <IntrBkSttlmDt>1967-08-13</IntrBkSttlmDt> <SttlmInf> <SttlmMtd>CLRG</SttlmMtd> <ClrSys> <Prtry>xx</Prtry> </ClrSys> </SttlmInf> <InstgAgt> <FinInstnId> <BIC>AAAAAAAAAAA</BIC> </FinInstnId> </InstgAgt> </GrpHdr> </FIToFICstmrDrctDbt> </root> 

我需要使用awk命令在单独的variables中提取每个标记值的值。 怎么做?

您可以使用awk ,如下所示,但是,这不是一个健壮的解决方案,如果xml格式不正确,将会失败,例如,如果在同一行上有多个元素。

 $ dt=$(awk -F '[<>]' '/IntrBkSttlmDt/{print $3}' file) $ echo $dt 1967-08-13 

我建议你使用适当的xml处理工具,如xmllint

 $ dt=$(xmllint --shell file <<< "cat //IntrBkSttlmDt/text()" | grep -v "^/ >") $ echo $dt 1967-08-13 

下面的代码将所有的标签值存储在一个数组中!希望这有助于。 但我仍然相信这不是一个最佳的方式来做到这一点。

 > perl -lne 'if(/>[^<]*</){$_=~m/>([^<]*)</;push(@a,$1)}if(eof){foreach(@a){print $_}}' temp A 2001-12-17T09:30:47 0 0.0 1967-08-13 CLRG xx AAAAAAAAAAA 

以下gawk命令使用记录分隔符正则表达式模式来匹配XML标记。 任何以<后跟至少一个非>并以>终止的任何东西都被认为是一个标签。 Gawk将每个RS匹配分配给RT变量。 标签之间的任何内容都将被解析为gawk分配给$ 0的记录文本。

 gawk 'BEGIN { RS="<[^>]+>" } { print RT, $0 }' myfile