【问题标题】:Parsing HTML on the command line; How to capture text in <strong></strong>?在命令行上解析 HTML;如何在<strong></strong>中截取文字?
【发布时间】:2013-09-15 19:38:09
【问题描述】:

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

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

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

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

“/strong”上的Grep 以获取带有目标的行;效果很好。

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

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

在我的 awk 或其他命令中,你有什么正确击中目标的提示吗?任何快速而肮脏的东西(grep、awk、sed、perl)都将不胜感激。

【问题讨论】:

标签: perl sed awk grep command-line-interface


【解决方案1】:

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

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

要通过 XPath 搜索,请尝试 xpup

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

【讨论】:

  • 感谢您的提示!我仍然关注这个线程来了解简单的 CLI 解析。感谢您的回答,TIL 关于pup! :D
【解决方案2】:

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

perl -Mojo -E '
    g("http://your.web")
    ->dom
    ->find("strong")
    ->each( sub { if ( $t = shift->text ) { say $t } } )'

【讨论】:

    【解决方案3】:

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

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

    输出:

    Target1NoSpaces
    Target2 With Spaces
    

    添加:

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

    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
    

    【讨论】:

    • +1 好方法,如果标签没有分成多行。
    • 这非常有效。标签在一行上,是单词或两个/三个单词的集合。输出是有规律的,而且总是一样的,所以做更多事情的方法是矫枉过正的。我喜欢 awk 和 perl 的实现,并将把它们收起来以备将来使用。谢谢大家提升我的知识!
    • @sudo_O Perl 正则表达式的多行特性实际上可以用于此。我在 Ruby 中添加了它的概念实现。迈克尔 J:欢迎 :)
    【解决方案4】:

    这是使用xmlstarlet的解决方案

    xml sel -t -v //strong input.html
    

    【讨论】:

      【解决方案5】:

      Trying to parse HTML without a real HTML parser is a bad idea. 话虽如此,对于您提供的具体示例,这是一个非常快速而肮脏的解决方案当一行中有多个&lt;strong&gt; 标签时,它将不起作用,当标签超过一行时,等等。

      awk -F '<strong>|</strong>' '/<strong>/ {print $2}' filename
      

      【讨论】:

        【解决方案6】:

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

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

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

        【讨论】:

        • 这可以匹配任何带有strong的文本。或者如果没有找到字段,则只是一个换行符。
        • @konsolebox 如果我们使用awk 进入解析html 的陷阱,我们可能会在这里待一会儿。我只是想在我的观点中展示它的用途,OP 可以酌情过滤/使其更健壮,或者接受我的建议并使用适当的 html 解析器。
        【解决方案7】:

        自从你标记了 perl

        perl -ne 'if(/(?:<strong>)(.*)(?:<\/strong>)/){print $1."\n";}' input.html
        

        【讨论】:

          猜你喜欢
          • 2013-01-17
          • 1970-01-01
          • 1970-01-01
          • 2011-03-23
          • 2012-01-19
          • 1970-01-01
          • 2013-05-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多