8

我正在尝试从如下所示的 HTML 输出中获取数据:

<strong>Target1NoSpaces</strong><span class="creator"> ....
<strong>Target2 With Spaces</strong><span class="creator"> ....

我正在使用管道列车将数据减少到我想要达到的目标。到目前为止,这是我的方法:

grep "/strong" output.html | awk '{print $1}'

Grep on "/strong" 以获取与目标的行;效果很好。

管道到 'awk'{print $1}'。这适用于目标没有空格的情况#1,但在目标有空格的情况#2 中失败..仅保留第一个单词,如下所示:

<strong>Target1NoSpaces</strong><span
<strong>Target2

在我的 awk 或其他命令中,您有任何关于正确击中目标的提示吗?任何快速而肮脏的东西(grep、awk、sed、perl)都会受到赞赏。

4

7 回答 7

12

Try pup,一个用于处理 HTML 的命令行工具。例如:

$ pup 'strong text{}' < file.html 
Target1NoSpaces
Target2 With Spaces

要通过 XPath 搜索,请尝试xpup.

或者,对于格式良好的 HTML/XML 文档,请尝试html-xml-utils.

于 2018-04-10T23:10:55.203 回答
7

一种使用方法mojolicious及其DOM解析器:

perl -Mojo -E '
    g("http://your.web")
    ->dom
    ->find("strong")
    ->each( sub { if ( $t = shift->text ) { say $t } } )'
于 2013-09-11T17:02:08.110 回答
6

在 grep 中使用 Perl 正则表达式的后视和前瞻功能。它应该比使用 awk 更简单。

grep -oP "(?<=<strong>).*?(?=</strong>)" file

输出:

Target1NoSpaces
Target2 With Spaces

添加:

Perl 的正则表达式在 Ruby 中的多重匹配的这种实现可以匹配多行中的值:

ruby -e 'File.read(ARGV.shift).scan(/(?<=<strong>).*?(?=<\/strong>)/m).each{|e| puts "----------"; puts e;}' file

输入:

<strong>Target
A
B
C
</strong><strong>Target D</strong><strong>Target E</strong>

输出:

----------
Target
A
B
C
----------
Target D
----------
Target E
于 2013-09-11T16:54:29.820 回答
4

这是使用xmlstarlet的解决方案

xml sel -t -v //strong input.html
于 2013-09-11T19:50:40.213 回答
3

尝试在没有真正的 HTML 解析器的情况下解析 HTML 是个坏主意。话虽如此,对于您提供的具体示例,这是一个非常快速而肮脏的解决方案。当一行中有多个标签时,它将不起作用<strong>,当标签超过一行时,等等。

awk -F '<strong>|</strong>' '/<strong>/ {print $2}' filename
于 2013-09-11T16:57:30.870 回答
3

您永远不需要grepwithawk并且字段分隔符不必是空格:

$ awk -F'<|>'  '/strong/{print $3}' file
Target1NoSpaces
Target2 With Spaces

但是,您确实应该为此使用适当的解析器。

于 2013-09-11T16:58:31.710 回答
1

既然你标记了 perl

perl -ne 'if(/(?:<strong>)(.*)(?:<\/strong>)/){print $1."\n";}' input.html
于 2013-09-11T17:04:00.817 回答