【问题标题】:Creating bash script to parse xml file to csv创建 bash 脚本以将 xml 文件解析为 csv
【发布时间】:2014-02-02 06:34:40
【问题描述】:

我正在尝试创建一个 bash 脚本来解析 xml 文件并将其保存到 csv 文件中。

例如:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <List>
    <Job id="1" name="John/>
    <Job id="2" name="Zack"/>
    <Job id="3" name="Bob"/>
</List>

我希望脚本将信息保存到 csv 文件中:

John | 1
Zack | 2
Bob  | 3

名称和 ID 将位于不同的单元格中。

有什么办法可以做到吗?

【问题讨论】:

标签: xml linux bash csv


【解决方案1】:

您发布了与您的pervious one 类似的查询。我再次建议使用 XML 解析器。你可以说:

xmlstarlet sel -t -m //List/Job -v @name -o "|" -v @id -n file.xml

它会返回

John|1
Zack|2
Bob|3

用于您的示例数据。

如果您希望它像您的示例中那样显示,请将输出通过管道传送到sedsed "s/|/\t| /"

【讨论】:

    【解决方案2】:

    试试这样的

    #!/bin/bash
    while read -r line; do
      [[ $line =~ "name=\""(.*)"\"" ]] && name="${BASH_REMATCH[1]}" && [[ $line =~ "Job id=\""([^\"]+) ]] &&  echo "$name | ${BASH_REMATCH[1]}"
    done < file 
    

    John 的行格式错误。修复后,示例输出

    John | 1
    Zack | 2
    Bob | 3
    

    【讨论】:

    • 本例中name="John/&gt;,John后面没有双重配额,所以建议将[[ $line =~ "name=\""(.*)"\"" ]]替换为[[ $line =~ "name=\""([^\"|/]*) ]]
    • @BMW 谢谢。我认为它不应该是格式错误的 xml,但如果它可以做到这一点或类似([A-Za-z]*)
    • 老兄,你能详细说明一下那个简短的脚本吗?我很困惑。 :) 尽管如此,它看起来非常好。
    【解决方案3】:

    扩展 xmlstarlet 方法:

    给定这个 xml 文件作为输入:

    <DATA>
      <RECORD>
        <NAME>John</NAME>
        <SURNAME>Smith</SURNAME>
        <CONTACTS>
          "Smith" LTD,
          London, Mtg Str, 12,
          UK
        </CONTACTS>
      </RECORD>
    </DATA>
    

    还有这个脚本:

    xmlstarlet sel -e utf-8 -t \
      -o "NAME, SURNAME, CONTACTS" -n \
      -m //DATA/RECORD \
      -o "\"" \
      -v $"str:replace(normalize-space(NAME), '\"', '\"\"')" -o "\",\"" \
      -v $"str:replace(normalize-space(SURNAME),      '\"', '\"\"')" -o "\",\"" \
      -v $"str:replace(normalize-space(CONTACTS), '\"', '\"\"')" -o "\",\"" \
      -o "\"" \
      -n file.xml
    

    您将获得以下输出:

    NAME, SURNAME, CONTACTS
    "John", "Smith", """Smith"" LTD, London, Mtg Str, 12, UK"
    

    【讨论】:

    • 这是一个很好的解决方案,而且很优雅。只是我得到了:编译错误:带有参数的元素 XSLT-with-param:由于规范化空间调用中的未闭合括号而无法编译选择表达式'str:replace';应该读为“str:replace(normalize-space(NAME), '\"', '\"\"')”
    • 谢谢。从 XML 中提取 URL 的任何其他人可能会发现 &amp;amp; 没有被转义。通过在sel 命令后添加-T 来解决此问题,例如xmlstarlet sel -T -e utf-8......(见stackoverflow.com/questions/46255304/…
    【解决方案4】:

    使用 sed

    sed -nr 's/.*id=\"([0-9]*)\"[^\"]*\"(\w*).*/\2 | \1/p' file
    

    另外,基于 BroSlow 的脚本,我合并了选项。

    #!/bin/bash
    
    while read -r line; do
      [[ $line =~ id=\"([0-9]+).*name=\"([^\"|/]*) ]] && echo "${BASH_REMATCH[2]} | ${BASH_REMATCH[1]}"
    done < file
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-13
      • 2013-07-24
      • 1970-01-01
      • 2021-01-09
      • 2012-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多