【问题标题】:How to grep my xml file and save output?如何grep我的xml文件并保存输出?
【发布时间】:2016-06-29 19:45:51
【问题描述】:

我只是给出了巨大的 xml 文件的一部分

   <caldata chopper="on" gain_1="0" gain_2="0" gain_3="0" impedance="(0,0)">
      <c0 unit="V">0.00000000e+00</c0>
      <c1 unit="Hz">4.00000000e+04</c1>
      <c2 unit="V/(nT*Hz)">8.35950000e-06</c2>
      <c3 unit="deg">-1.17930000e+02</c3>
    </caldata>
    <caldata chopper="on" gain_1="0" gain_2="0" gain_3="0" impedance="(0,0)">
      <c0 unit="V">0.00000000e+00</c0>
      <c1 unit="Hz">5.55810000e+04</c1>
      <c2 unit="V/(nT*Hz)">4.43400000e-06</c2>
      <c3 unit="deg">-1.58280000e+02</c3>
    </caldata>
    <caldata chopper="on" gain_1="0" gain_2="0" gain_3="0" impedance="(0,0)">
      <c0 unit="V">0.00000000e+00</c0>
      <c1 unit="Hz">6.00000000e+04</c1>
      <c2 unit="V/(nT*Hz)">3.63180000e-06</c2>
      <c3 unit="deg">-1.67340000e+02</c3>
    </caldata>
    <caldata chopper="off" gain_1="0" gain_2="0" gain_3="0" impedance="(0,0)">
      <c0 unit="V">0.00000000e+00</c0>
      <c1 unit="Hz">4.00000000e-01</c1>
      <c2 unit="V/(nT*Hz)">1.07140000e-02</c2>
      <c3 unit="deg">1.48080000e+02</c3>
    </caldata>
    <caldata chopper="off" gain_1="0" gain_2="0" gain_3="0" impedance="(0,0)">
      <c0 unit="V">0.00000000e+00</c0>
      <c1 unit="Hz">5.55800000e-01</c1>
      <c2 unit="V/(nT*Hz)">1.33250000e-02</c2>
      <c3 unit="deg">1.39110000e+02</c3>
    </caldata>
    <caldata chopper="off" gain_1="0" gain_2="0" gain_3="0" impedance="(0,0)">
      <c0 unit="V">0.00000000e+00</c0>
      <c1 unit="Hz">7.72300000e-01</c1>
      <c2 unit="V/(nT*Hz)">1.57750000e-02</c2>
      <c3 unit="deg">1.29560000e+02</c3>

我试过这样

grep '<c1 unit="Hz"' *.xml | cut -f2 -d">"|cut -f1 -d"<"

工作得很好,我真正想要的是仅在以下情况下输出 caldata chopper="off" 并将我的输出保存到文件中。 如何做到这一点?

【问题讨论】:

  • 使用 XML/HTML 解析器(xmllint、xmlstarlet ...)。
  • 您的文件有多大? 100s mb 还是 gbs?
  • @vtd-xml-author 96,5kB,一点也不大!

标签: xml shell xml-parsing grep


【解决方案1】:

一种解决方案是使用 XML grep,例如 xgrep。我自己在我的机器上试了一下,得到了这个:

$ xgrep -t -x '//caldata[@chopper="off"]/c1[@unit="Hz"]/text()' test.xml 
4.00000000e-01
5.55800000e-01
7.72300000e-01

秘诀在于 XPath 表达式:

  • //caldata[@chopper="off"] - 获取所有caldata 元素,chopper 属性等于off
  • c1[@unit="Hz"] - 从 caldata 元素中,得到 c1 元素,其 unit 属性等于 Hz;
  • text() - 从那些 c1 元素中,仅获取文本内容。

要将其保存到输出文件,只需使用 shell 中的 &gt; 重定向器。我们只需要在命令后面加上,然后加上文件名就可以得到输出:

$ xgrep -t -x '//caldata[@chopper="off"]/c1[@unit="Hz"]/text()' test.xml  > output.xml
$ cat output.xml 
4.00000000e-01
5.55800000e-01
7.72300000e-01

我不知道您是否可以使用这样的自定义工具,当然,但如果可以,它可能是您的最佳解决方案。

【讨论】:

  • Obrigado,nordestino!如何将输出保存到文本文件?
  • De nada ;) 我已经编辑了答案以解释如何将输出保存到文件中。
【解决方案2】:

这样就可以了:

cat file.xml | awk '/chopper="off"/,/calcdata/{print}' | grep 'unit="Hz"' | sed 's/^.*">//;s/<.*$//'

第一个命令 (awk) 只使用包含 chopper="off" 的块。第二个命令 (grep) 只使用带有您想要的数字的行。第三个命令 (sed) 取行中的数字。

【讨论】:

    【解决方案3】:

    由于您使用的是 grep,我将假设您使用 *nix 和命令行类型的解决方案

    在这种情况下,您可能希望查看类似 zorba 的东西,它会使用 xquery 解析您的输入文档并输出您想要的部分。

    如果数据中的容器元素是 foo,xquery 将包含:

    for $c in /foo/caldata
    return if ($c/@chopper="on")
    then $c else ""
    

    【讨论】:

      猜你喜欢
      • 2012-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多