客观的:1)返回一个姓名和<a>
2) 评估多个 HTML 表格行中的单元格值,有条件地返回 0 或 1
我curl -s http://[server-fqdn]/stats/servers?t=db | grep 'tr class="server"
这样做会返回不同数量的行,如代码片段所示。在本例中,我列出了数据库服务器。
行片段(注意:整行字符数在 2,000 到 2,150 个字符之间)
<tr class="server"><td class=val><a name="srv_backend_3306/server"></a></td> [cut away] <td class=val>1d3h UP</td>
挑战:提取值姓名并评估第一个<a>
标签的内容<td class=val></td>
(如果包含单词 UP,则返回 0,否则返回 1)。
我可以扩展上面描述的curl命令,添加| cut -d\> -f3 | cut -d\" -f2
并得到姓名- 但如何得到其他结果呢?我没有该单元格的唯一标识符,并且cut
由于表格生成的动态性,使用并不能完全减少它。
答案1
这里有一点片段其灵感来自于StackOverflow 的答案您可以与本机 bash 一起使用,您将有一个函数来读取输入的内容,然后使用另一个函数来解析多姆内容 :
#!/bin/bash
cr=1
ac=""
read_dom () {
local IFS=\>
read -d \< ENTITY CONTENT
local ret=$?
TAG_NAME=${ENTITY%% *}
ATTRIBUTES=${ENTITY#* }
return $ret
}
parse_dom () {
if [[ $TAG_NAME == "a" ]] ; then
eval local $ATTRIBUTES
ac=`cut -d "=" -f2 <<< "$ATTRIBUTES" | tr -d '"'`
fi
if [[ $TAG_NAME == "td" && "$(cut -d= -f1 <<< $ATTRIBUTES)" == "class" && $CONTENT == *"UP"* ]] ; then
cr=0
fi
}
while read_dom; do
parse_dom
done <<< "$(curl -s http://[server-fqdn]/stats/servers?t=db | grep 'tr class="server")"
echo "<a> tag content : $ac"
echo "return value for <td> check : $cr"
输出 :
<a> tag content : srv_backend_3306/server
return value for <td> check : 0
答案2
找到了一个解决方案 - 它可以完成工作,但请随意提出改进建议;)
#!/bin/bash
curl -s http://[server-fqdn]/stats/servers?t=db | grep 'tr class="server"' > hastats.html
for i in `cat hastats.html | grep 'tr class="server"' | cut -d\> -f3 | cut -d\" -f2` ; do
grep $i hastats.html | ( ! grep -P " UP" -q)
echo $i $?
done
对于该服务器,这会返回例如srv_backend_3306 1
,这意味着已确定在该特定行中出现了前面有空格的单词 UP。在这种情况下,我确信这个特定的单词要么不存在,要么对于这些特定行中的每一行只出现一次。
否定! grep -P ' UP' -q
返回的错误代码,通常为“0”表示“发现发生” - 我们希望由于特定原因返回“1”。
感谢您的建设性意见。