在xml中使用awk字段分隔符

时间:2016-09-13 03:14:44

标签: awk

我有一个包含以下数据的xml文件。

<record record_no = "2" error_code="100">&quot;18383531&quot;;&quot;22677833&quot;;&quot;21459732&quot;;&quot;41001&quot;;&quot;394034&quot;;&quot;0208&quot;;&quot;Prime Lending - ;Corporate  - 2201&quot;;&quot;&quot;;&quot;Prime Lending - Lacey - 2508&quot;;&quot;Prime Lending - Lacey - 2508&quot;;&quot;1&quot;;&quot;rrvc&quot;;&quot;Tiffany Poe&quot;;&quot;HEIDI&quot;;&quot;BUNDY&quot;;&quot;000002274&quot;;&quot;2.0&quot;;&quot;18.0&quot;;&quot;2&quot;;&quot;362661&quot;;&quot;Rejected by IRS&quot;;&quot;A1AAA&quot;;&quot;20160720&quot;;&quot;1021&quot;;&quot;HEDI &amp; Bundy&quot;;&quot;4985045838&quot;;&quot;PPASSESS&quot;;&quot;Web&quot;;&quot;3683000826&quot;;&quot;823&quot;;&quot;IC W2&quot;;&quot;&quot;;&quot;&quot;;&quot;&quot;;&quot;&quot;;&quot;Rapid_20160801_Monthly.txt&quot;;&quot;20160720102100&quot;;&quot;&quot;;&quot;20160803095309&quot;;&quot;286023&quot;;&quot;RGT&quot;;&quot;1&quot;;&quot;14702324400223&quot;;&quot;14702324400223&quot;;&quot;0&quot;;&quot;OMCProcessed&quot;

我正在使用以下代码:

cat RR_00404.fin.bc_lerr.xml.bc| awk 'BEGIN { FS=OFS=";" }/<record/ { gsub(/&quot;/,"\"");  gsub(/.*=" ">.*/,"",$1);print $1,$40,$43,$46 ,"'base_err_xml'", "0",$7; }' 

我们的想法是:

  1. &quote;替换为"
  2. 提取error_code
  3. 打印";分隔值。
  4. 使用sqlldr加载(不用担心这个)。
  5. 要解决的问题:

    1. 文本中有;。例如Prime Lending -; Corporate - 2201
    2. &amp;
    3. 输出:

      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"
      

1 个答案:

答案 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">

请注意,$1record_no$2error_code$9正确包含分号作为文字内容。

显然,您可以将这两个组件封装在shell函数中,以避免需要单独的文件。