【问题标题】:Bash regex can't match xml? [duplicate]Bash正则表达式无法匹配xml? [复制]
【发布时间】:2015-07-31 05:39:27
【问题描述】:

我正在尝试集成 Jenkins 以从关键跟踪器中获取故事,如果它们已包含在构建中,则这些故事已标记为已完成(我们已经在 jenkins 和关键跟踪器上与 github 集成)。使用 curl,我可以使用关键的 web api 获取相关的故事,它返回一个带有故事值的 xml。我在 regexraptor.net 上测试了一个 bash 正则表达式(<current_state>(.*)<\/current_state>),以匹配字符串中的节点值(在本例中为<story><current_state>this</current_state></story>),目标是返回this(元素中所需的文本)用于分配给 bash 变量。 regexraptor 告诉我它匹配,但是当我尝试输出文本时,它出现空白。 目前,我的输出代码如下:

$XML_STRING='<current_state>this</current_state>'
[[ $XML_STRING =~ '<current_state>(.*)<\/current_state>' ]]
echo "${BASH_REMATCH[1]}"

什么都不输出。 我怎样才能让它输出'this'?

由于我在工作中使用的服务器上的 Oracle Linux 发行版的限制,如果可能的话,我需要使用纯 bash 来使它工作。 sed 和 grep 可用,但我没有运气,他们找到了匹配项,但输出了整个 xml 流而不是我想要的单个单词值,我只是无法让 grep 工作。 xpath 不可用,xmllint 也被证明不可行

【问题讨论】:

  • xmllint 是怎么失败的?我经常将其用作通用 XPath 查询工具 (xmllint --xpath //some_query -)。您可以使用具有实际 XML 解析器的 Python 之类的东西吗?您可以发布一个您尝试解析的实际 XML 的示例吗?
  • @larsks,许多旧版本的 xmllint 没有--xpath 选项(这也是我倾向于建议xmlstarlet 的部分原因——当然,它不太可能被安装,但是如果已安装,则保证具有相关功能)。但是,是的,使用 Python 往往是一个不错的选择,并且可能适用于 OP。
  • @larsks xmllint 没有失败,它只是在服务器和服务器发行版的包管理器上不可用,与 xmlstarlet 相同。查尔斯提供的帖子给了我答案(sakurashinken 的答案也是如此)。不幸的是,由于 bash 处理字符串的方式,我最终决定放弃直接的 bash 方法并编写一个命令行 ruby​​ gem 来处理 Jenkins/Pivotal Tracker 集成。

标签: regex xml linux bash


【解决方案1】:

Bash 正则表达式不带引号。以下代码在我的 mac 上以 bash 的形式返回“this”:

XML_STRING='<current_state>this</current_state>'
[[ $XML_STRING =~ \<current_state\>(.*)<\/current_state\> ]]
echo "${BASH_REMATCH[1]}"

【讨论】:

    【解决方案2】:

    假设我们的 XML 看起来像 this question 中的 XML,您可以像这样使用 xmllint 提取 current_state 值:

    $ xmllint --xpath 'string(/stories/story/current_state)' myfile.xml
    accepted
    

    如果输入文件包含多个故事,这将只返回第一个。您可以通过为您的 XPath 表达式提供适当的索引来选择其他故事:

    $ xmllint --xpath 'string((/stories/story/current_state)[2])' myfile.xml 
    unscheduled
    

    如果你真的有:

    XML_STRING='<current_state>this</current_state>'
    

    你可以像这样在中间获取值文本:

    $ echo "$XML_STRING" | cut -f2 -d'>' | cut -f1 -d'<'
    this
    

    【讨论】:

      【解决方案3】:

      通过以下方式在 linux 上检查您的文件:

      cat -vte filename
      

      如果你在第二个位置看到奇怪的 ^@ 或任何其他奇怪的东西,那么你的文件里面有一些控制字符,这会给你带来问题。此外,您可能想要检查/更改 windows 结束行到 linux 结束行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-17
        • 2011-10-17
        • 2023-03-14
        • 2018-08-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多