使用bash解析HTML表列

时间:2015-09-09 13:29:06

标签: xml bash xpath html-parsing xmllint

我正在尝试从HTML中的表中提取3列。我需要添加主机名,产品+区域和日期。所以它们将是第1,3,4列。

Floor()

我想得到:

<div class="table sectionedit2">
  <table class="inline">
    <tr class="row0">
      <th class="col0 centeralign">hostname</th>
      <th class="col1 centeralign">AKA (Client hostname)</th>
      <th class="col2 leftalign">Product + Region</th>
      <th class="col3 centeralign">date added</th>
      <th class="col4 centeralign">  decom. date  </th>
      <th class="col5 centeralign">           builder           </th>
      <th class="col6 centeralign">  build cross-checker  </th>
      <th class="col7 leftalign"> <strong>decommissioner</strong></th>
      <th class="col8 centeralign">customer managed filesystems</th>
      <th class="col9 centeralign">  only company has root?  </th>
    </tr>
    <tr class="row1">
      <th class="col0 centeralign">HostName01</th>
      <td class="col1 leftalign">Host01</td>
      <td class="col2 leftalign">EU</td>
      <td class="col3 centeralign">2007-01-01</td>
      <td class="col4 leftalign"></td>
      <td class="col5 centeralign">Me</td>
      <td class="col6 centeralign">You</td>
      <td class="col7 leftalign">Builder01</td>
      <td class="col8 leftalign">xChecker01</td>
      <td class="col9 centeralign">yes</td>
    </tr>
   <tr class="row2">
     <th class="col0 centeralign">HostName02</th>
     <td class="col1 leftalign">Host02</td>
     <td class="col2 leftalign">U.S</td>
     <td class="col3 centeralign">2008-09-29</td>
     <td class="col4 leftalign"></td>
     <td class="col5 leftalign">Me01</td>
     <td class="col6 leftalign">You01</td>
     <td class="col7 leftalign">Builder02</td>
     <td class="col8 leftalign">xChecker02</td>
     <td class="col9 centeralign">yes</td>

之前我尝试剥离HTML标记并使用awk,尽管表中的某些列是空的。这意味着我没有获得所有行的第1,3和4列。

我正在尝试使用:

Hostname     Product + Region   Date added

HostName01   EU                 2007-01-01

HostName02   U.S                2008-09-29

这给了我第二列,我试过“[0]”哪个不起作用,我不知道如何一次获得多个列。

2 个答案:

答案 0 :(得分:3)

您可以执行以下操作:

  • 使用XPath表达式运行xmllint --xpath,使用position()=只抓取第1,3和4列://table/tr/*[position()=1 or position()=3 or position()=4]
  • 管道通过perl -pe "s/<th class=\"col0/\n<th class=\"col0/g"等,去除标记并将其拆分为单独的行
  • 通过grep -v '^\s*$'管道以删除空行
  • 在最后通过column -t管道以打印它

像这样:

xmllint --html \
  --xpath "//table/tr/*[position()=1 or position()=3 or position()=4]" \
    table.log \
    | perl -pe "s/<th class=\"col0/\n<th class=\"col0/g" \
    | perl -pe 's/<tr[^>]+>//' \
    | perl -pe 's/<\/tr>//' \
    | perl -pe 's/<t[dh][^>]*>//' \
    | perl -pe 's/<\/t[dh]><t[dh][^>]*>/|/g' \
    | perl -pe 's/<\/t[dh]>//' \
    | grep -v '^\s*$' \
    | column -t -s '|'

以上假设HTML文档位于文件table.log中(这似乎是HTML文件的奇怪名称,但它似乎是问题中使用的名称...)。如果文档实际上在其他*.html文件中,当然只需输入实际文件名。

这会给你这样的输出:

hostname    Product + Region  date added
HostName01  EU                2007-01-01
HostName02  U.S               2008-09-29

答案 1 :(得分:1)

假设你的html是格式良好的xml,可以做到:

xmlstarlet sel -t -m '//table/tr' -v '*[contains(@class,"col0")]' -o $'\t' \
                                  -v '*[contains(@class,"col2")]' -o $'\t' \
                                  -v '*[contains(@class,"col3")]' -n       \
    file.html
hostname    Product + Region    date added
HostName01  EU  2007-01-01
HostName02  U.S 2008-09-29