我正在尝试使用sed或grep解析页面https://extensions.typo3.org/extension/tt_news/的版本号和相应的日期。 更具体地说,我对以下html部分感兴趣:
<tr>
<td class="align-middle">
<strong>3.6.0</strong> /
<span class="ter-ext-state-beta">beta</span>
<br />
<small>
April 06, 2014
</small>
</td>
<td class="align-middle">
tt_news for TYPO3 4.5 - 6.2 (compatibility update)
</td>
<td class="align-middle">
<strong>4.5.0 - 6.2.99</strong>
</td>
<td class="align-middle">
<a class="btn btn-primary" title="Size: 2.58MB" href="/extension/download/tt_news/3.6.0/zip/">
<strong>
Download ZIP Archive
</strong>
</a>
</td>
</tr>
我想从每个部分中获取版本(在 strong 标记之间)和日期(在 small 标记之间)。 到目前为止,我所有的尝试都失败了,我可以将问题缩小到非常简单的程度。 我已经测试了以下正则表达式,该正则表达式仅尝试在regex101.com上获取 tr 标记,后跟空格和 td 标记,在那里,它工作得很好:
<tr>\s*<td
它给了我5次正确的比赛。以下一项也可以正常工作:
<tr[^>]*>\s*<td
它产生38个结果,因为它包含具有css class属性的那些tr标记。 但是,无论是grep还是sed都无法使它正常工作。一旦包含\ s,就不再有任何匹配项。看起来像这样:
cat tt_news_history | grep '<tr>\s*<td'
没有点击。
cat tt_news_history | grep '<tr>'
6次点击。
cat tt_news_history | grep '<tr[^>]*>'
很多点击(未计算)。与sed相同。 我究竟做错了什么?为什么不能使用\ s? 感谢您的提示。
答案 0 :(得分:2)
GNU grep有一个-z
选项,可使\s
匹配输入中的换行符,例如:
cat tt_news_history | grep -z '<tr>\s*<td'
信息文档中的相关片段:
“-z”“-空数据” 将输入和输出数据视为行序列,每行终止 用零字节(ASCII NUL字符)代替换行符。 像“ -Z”或“ --null”选项一样,该选项可与 诸如“ sort -z”之类的命令来处理任意文件名。
(...)
- 如何匹配线段?
标准grep无法执行此操作,因为它基本上是基于行的。 因此,仅使用“ [:space:]”字符类是不匹配的 以您可能期望的方式换行。
使用GNU的“ grep”选项“ -z”(“-null-data”),每个输入“行”为 以一个空字节终止; *注意其他选项::。因此,您可以匹配 输入中的换行符,但通常如果匹配则整个 输入是输出,因此这种用法通常与 输出抑制选项,例如“ -q”,例如:
printf'foo \ nbar \ n'| grep -z -q'foo [[:space:]] + bar'
如果这还不够,您可以在输入之前进行转换 转到“ grep”或转到“ awk”,“ sed”,“ perl”或许多其他实用程序 旨在跨线运行。