使用bash从html表中提取单元格值

时间:2013-03-19 16:31:37

标签: html regex bash html-parsing

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

以下是我的网页示例


<table border="1" bordercolor="#FFCC00" style="background-color:#FFFFCC" width="100%" cellpadding="3" cellspacing="3">

<tr align="center">

<th>Environment</th><th>Release Track</th><th>Artifact</th><th>Name</th><th>Build #</th><th>Cert Idn</th><th>Build Idn</th><th>Request Status</th><th>Update Time</th><th>Log Info.</th><th>Initiator</th>

</tr>

<tr>
<td>DEV03</td><td>2.1.0</td><td>abpa</td><td>ecom-abpa-ear</td><td>204</td><td>82113</td><td>171242</td><td>Deployed</td><td>3/18/2013 3:10:58 PM</td><td width="70">Log info</a></td><td>CESAR</td>
</tr>

<tr>
<td>DEV03</td><td>2.1.0</td><td>abpa</td><td>abpa_dynamic_config_properties</td><td>20</td><td>82113</td><td>167598</td><td>Deployed</td><td>3/18/2013 2:32:27 PM</td><td width="70">Log info</a></td><td>CESAR</td>

</tr>

</table>

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

“已部署”

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

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

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

我尝试了以下内容:

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

但这只是为了“已部署”

有什么想法吗?

5 个答案:

答案 0 :(得分:3)

您应该使用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个表列中的值。

答案 1 :(得分:3)

您还可以使用我的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]'

答案 2 :(得分:2)

您可以尝试xshXML::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更好一点(我必须删除</a>以使脚本工作)。

答案 3 :(得分:2)

请注意,您的文档输出格式错误(缺少一些开放<a>),是正常/已被删除还是错字?否则,这是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

答案 4 :(得分:0)

又快又脏:

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。