我有一个包含以下数据的xml文件。
<record record_no = "2" error_code="100">"18383531";"22677833";"21459732";"41001";"394034";"0208";"Prime Lending - ;Corporate - 2201";"";"Prime Lending - Lacey - 2508";"Prime Lending - Lacey - 2508";"1";"rrvc";"Tiffany Poe";"HEIDI";"BUNDY";"000002274";"2.0";"18.0";"2";"362661";"Rejected by IRS";"A1AAA";"20160720";"1021";"HEDI & Bundy";"4985045838";"PPASSESS";"Web";"3683000826";"823";"IC W2";"";"";"";"";"Rapid_20160801_Monthly.txt";"20160720102100";"";"20160803095309";"286023";"RGT";"1";"14702324400223";"14702324400223";"0";"OMCProcessed"
我正在使用以下代码:
cat RR_00404.fin.bc_lerr.xml.bc| awk 'BEGIN { FS=OFS=";" }/<record/ { gsub(/"/,"\""); gsub(/.*=" ">.*/,"",$1);print $1,$40,$43,$46 ,"'base_err_xml'", "0",$7; }'
我们的想法是:
"e;
替换为"
error_code
"
和;
分隔值。sqlldr
加载(不用担心这个)。要解决的问题:
;
。例如Prime Lending -
; Corporate - 2201
&
输出:
100;"20160803095309";"1";"1";"base_err_xml";"0";"Prime Lending
100;"286023";"14702324400223";"OMCProcessed";"base_err_xml";"0";"Prime Lending - Corporate - 2201"
100;"286024-1";"";"OMCProcessed";"base_err_xml";"0";"Prime Lending - Corporate - 2201"
答案 0 :(得分:1)
awk
是这项工作的错误工具,没有一些预处理。在这里,我们使用XMLStarlet作为第一遍(解码所有XML实体并将属性拆分为单独的字段),并使用GNU awk作为第二行(读取这些字段并执行您实际需要的任何转换或逻辑):
#!/bin/sh
# reads XML on stdin; puts record_no in first field, error code in second,
# ...record content for remainder of output line.
xmlstarlet sel -t -m '//record' \
-v ./@record_no -o ';' \
-v ./@error_code -o ';' \
-v . -n
......并且,GNU awk documentation ...
#!/bin/env gawk -f
# must be GNU awk for the FPAT feature
BEGIN {
FPAT = "([^;]*)|(\"[^\"]*\")"
}
{
print "NF = ", NF
for (i = 1; i <= NF; i++) {
printf("$%d = <%s>\n", i, $i)
}
}
在这里,我们对gawk
所做的只是展示字段如何分割,但很明显,您可以根据自己的需要修改脚本。
以下引用了您的给定输入文件的上述输出子集(当扩展为实际有效的XML时):
$1 = <2>
$2 = <100>
$9 = <"Prime Lending - ;Corporate - 2201">
请注意,$1
是record_no
,$2
是error_code
,$9
正确包含分号作为文字内容。
显然,您可以将这两个组件封装在shell函数中,以避免需要单独的文件。