【问题标题】:Remove XML tabs & newline within same tag in Bash在 Bash 中的同一标记内删除 XML 选项卡和换行符
【发布时间】:2021-04-17 08:29:38
【问题描述】:

我有如下 XML 数据,但名称和结束标记不同。

这种格式易于阅读,但在数据提取方面存在问题。

XML 源数据

<Device name="MotorA" 
type="stepper" 
factor="2" 
profile="high" 
SyncMode="false">

<Param name="Gain" 
type="Baic" 
PID="Standard" 
valid="true" 
version="1.2"/>

预期输出

<Device name="MotorA" type="stepper" factor="2" profile="high" SyncMode="false">
<Param name="Gain" type="Baic" PID="Standard" valid="true" version="1.2"/>

如何删除同一标签(一个标签,一行)内的制表符/换行符,以便在 Bash 脚本中提取数据?

环境是“Linux develop 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux”

【问题讨论】:

  • 在您的示例中,不仅 同一标签内的换行符 被删除,而且标签之间的空行也被删除。你应该明确这是否是需要的。

标签: xml bash


【解决方案1】:

&lt;Device [...]&gt; 节点的结束 &lt;/Device&gt; 标记在哪里?您的 XML 数据表明 &lt;Param [...]&gt; 节点实际上是子节点而不是兄弟节点。

我建议您使用 XML 解析器处理 XML,例如 。幸运的是xidel 对未封闭的标签相当宽容:

$ xidel -s "input.xml" -e . --output-node-format=xml
<Device name="MotorA" type="stepper" factor="2" profile="high" SyncMode="false">

<Param name="Gain" type="Baic" PID="Standard" valid="true" version="1.2"/></Device>

注意到结束 &lt;/Device&gt; 标记了吗?

或适当缩进:

$ xidel -s "input.xml" -e . --output-node-format=xml --output-node-indent
<Device name="MotorA" type="stepper" factor="2" profile="high" SyncMode="false">
  <Param name="Gain" type="Baic" PID="Standard" valid="true" version="1.2"/>
</Device>

【讨论】:

    【解决方案2】:

    以下内容对我有用(其中srcdatas.xml 是一个 XML 文件,其中包含您问题中的 xml 源数据)。

    awk 'BEGIN {RS=""}{gsub(/\n/, " ", $0); print $0}' srcdatas.xml
    

    Windows Subsystem for Linux (WSL) 上测试,特别是

    Ubuntu 20.04.2 LTS (GNU/Linux 4.4.0-19041-Microsoft x86_64)
    

    灵感来自以下关于serverfault

    的问题

    linux - remove line break using AWK

    【讨论】:

    • 感谢您的回答,但它删除了所有换行符。我们可以删除同一标签中的换行符并使其成为“一个标签,一行”谢谢
    • @AlbertLiang 我写道它在我的环境中工作。我猜你有不同的环境。也许您应该edit您的问题并添加更多详细信息,例如您所在的平台。你在Windows系统上吗?请注意,我只是从您的问题中复制了 XML 并将其粘贴到我使用 vi editor 创建的文本文件中。
    • 感谢您的提醒。我的环境是“Linux develop 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux”
    • @AlbertLiang 我无法访问 linux 系统。我假设上述命令在您的系统上的输出是一行。如果是这样,则尝试将上述命令的输出通过管道传送到另一个 awk(或 sed)命令,该命令在 [XML] 结束标记的 &gt; 和以下开始标记的 &lt; 之间插入换行符.
    【解决方案3】:

    如果ed 可用/可接受。注意ed不是解析xml文件的工具。

    #!/usr/bin/env bash
    
    ed -s file.xml <<-EOF
      g/^</;/>$/j
      ,p
      Q
    EOF
    

    或单独的ed 脚本,script.ed

    g/^</;/>$/j
    ,p
    Q
    

    然后

    ed -s file.xml < script.ed
    

    内嵌

    printf '%s\n' 'g/^</;/>$/j' ,p Q | ed -s file.xml
    

    如果需要就地编辑 file.xml,请将 Q 更改为 w

    【讨论】:

      【解决方案4】:

      此命令删除所有制表符和换行符,并为每个以&gt;结尾的标签添加换行符

      tr -d '\t\n' < yourxml | sed -e $'s/>/>\\\n/g'
      

      经过测试

      • Mac bash:GNU bash,版本 4.4.12(1)-release (x86_64-apple-darwin15.6.0)
      • Ubuntu bash:GNU bash,版本 5.0.17(1)-release (x86_64-pc-linux-gnu)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-31
        • 2021-08-12
        • 1970-01-01
        • 1970-01-01
        • 2017-08-11
        • 2015-06-07
        • 2021-09-13
        • 1970-01-01
        相关资源
        最近更新 更多