【问题标题】:Extract cell value from html table using bash使用bash从html表中提取单元格值
【发布时间】:2013-03-08 11:06:20
【问题描述】:

我正在尝试创建一个 BASH/Perl 脚本,该脚本将从动态 html 表中获取特定值。

这是我的页面示例

a>
环境 发布轨道 工件 名称 版本号 Cert Idn Build Idn 请求状态 更新时间 日志信息。 Initiator
DEV03 2.1.0 abpa ecom-abpa-ear 204 82113 171242 已部署 3/18/2013 3:10:58 PM 日志信息CESAR
DEV03 2.1.0 abpa abpa_dynamic_config_properties 20 82113 167598 已部署 3/18/2013 2:32:27 PM 日志信息 td> CESAR

我的目标是从此单元格中获取此值。

“部署”

另一种看待它的方式......

检索“请求状态”列下的所有数据

“已部署”的值是动态的,可能会发生变化。

我尝试了以下方法:

sed -e 's/>/>\n/g' abpa_cesar_status.txt | egrep -i "^\s*[A-Z]+</td>
" | sed -e 's|</td>||g' | grep Deployed

但这仅适用于“已部署”

有什么想法吗?

【问题讨论】:

  • 你提到了 Perl。所以使用HTML::TableExtract
  • 不要使用正则表达式解析 HTML。您无法使用正则表达式可靠地解析 HTML,并且您将面临悲伤和挫败感。一旦 HTML 与您的期望发生变化,您的代码就会被破坏。有关如何使用已经编写、测试和调试过的 Perl 模块正确解析 HTML 的示例,请参阅 htmlparsing.com/perl
  • 真的 不要使用正则表达式: stackoverflow.com/a/1732454/140740
  • 您的文档输出格式不正确,是正常/预期的还是错字?这是一个格式良好的版本:pastebin.com/R8RGX1T9
  • 我无法查看格式正确的版本,因为我的工作阻止了这些链接

标签: html regex bash html-parsing


【解决方案1】:

您应该使用 xmllint 之类的解析器来执行此操作。

使用xmllint,您可以根据 xpath 提取元素。

例如:

$ xmllint --html --format --shell file.html <<< "cat //table/tr/td[position()=8]/text()"
/ >  -------
Deployed
 -------
Deployed
/ >

上述命令中的 xpath //table/tr/td[position()=8]/text() 返回表格第 8 列的值。

【讨论】:

    【解决方案2】:

    又快又脏:

    cat your_html_file | perl -pe "s/^<\/?table.*$//g;s/^<tr .*$//g;s/<tr> (<td>.*?){8}//g;s/<th.*$//g;s/<\/.*$//g" | sed '/^$/d'
    

    但是,您不应该这样做。使用现有的(Perl?)软件来解析 html 并提取您的值。

    编辑:由于您更改了代码(添加了空格),这不再起作用。 QED。

    【讨论】:

      【解决方案3】:

      你可以试试xsh,一个围绕XML::LibXML的包装器:

      open :F html abpa_cesar_status.txt ;
      $status = count(//table/tr[1]/th[.="Request Status"]/preceding-sibling::th) ;
      ls //td[count(preceding-sibling::td)=$status] ;
      

      为了使用它,您必须使您的 html 格式更好一些(我必须删除 &lt;/a&gt; 才能使脚本正常工作)。

      【讨论】:

      • 看起来不错的概念/工具
      【解决方案4】:

      您也可以使用我的Xidel 获取第 8 列中的所有内容:

      xidel your_table.html -e '//table//tr/td[8]'
      

      或者如果列位置也可以改变,先获取列号:

      xidel your_table.html -e 'column:=count(//table//th[.="Request Status"]/preceding-sibling::*)+1' -e '//table//tr/td[$column]'
      

      【讨论】:

        【解决方案5】:

        请注意,您的文档输出格式不正确(缺少一些开头&lt;a&gt;),这是正常/预期的还是错字?否则,这里是well-formed version

        命令

        我喜欢 xmlstarlet,用于简短测试的简单直接的 XPath:

        xmlstarlet sel -t -m "//table/tr/td[position()=8]" -v "./text()" -n 
        

        说明

        sel   (or select)        - Select data (mode) or query XML document(s) (XPATH, etc)
        -t or --template         - start a template
        -m or --match <xpath>    - match XPATH expression
        -v or --value-of <xpath> - print value of XPATH expression
        -n or --nl               - print new line
        

        输出

        Deployed
        Deployed
        # plus empty-cell
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-26
          • 1970-01-01
          • 2021-10-15
          • 2012-10-16
          • 2013-01-10
          相关资源
          最近更新 更多