你如何在这条线上使用'grep'? Linux的

时间:2014-03-29 02:25:48

标签: linux bash

<span class="cur_wind">with 3km/h SSW winds</span><hr class="hr_sm" /></td>

我想用3km / h的SSW风来提取单词&#34;&#34; (注意这个字符串会改变,所以硬编码它不会工作)从上面的行使用&#39; grep&#39;命令。我已经尝试了很长时间而且完全迷失了。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:2)

这是一个GNU grep解决方案,它使用-P激活对PCRE的支持(Perl兼容的正则表达式):

grep -Po '"cur_wind">\K[^<]+' \
  <<<'<span class="cur_wind">with 3km/h SSW winds</span><hr class="hr_sm" /></td>'
  • -o指定只输出匹配的字符串
  • \K是一项PCRE功能,可以删除到目前为止匹配的所有内容;这允许为更具体的匹配提供上下文,而不在匹配中包含该上下文。

另一种选择是使用后视断言来代替\K

 grep -Po '(?<="cur_wind">)[^<]+' \
  <<<'<span class="cur_wind">with 3km/h SSW winds</span><hr class="hr_sm" /></td>'

当然,这种匹配依赖于输入字符串的特定格式(空格,单引号和双引号,属性排序......)以及grep的基本问题不了解数据的结构,因此很脆弱。

因此,总的来说,正如其他人所指出的那样,grep是错误的工具。

OSX 上,假设输入是XML(或XHTML),您可以使用stock xmllint实用程序和XPath表达式进行强大的解析:

xmllint --xpath '//span[@class="cur_wind"]/text()' - <<<\
 '<td><span class="cur_wind">with 3km/h SSW winds</span><hr class="hr_sm" /></td>'

以下是使用第三方实用程序的类似解决方案,multi-platform web-scraping utility xidel(处理HTML和XML):

xidel -q -e '//span[@class="cur_wind"]' - <<<\
 '<td><span class="cur_wind">with 3km/h SSW winds</span><hr class="hr_sm" /></td>'

答案 1 :(得分:1)

尝试sed:

echo '<span class="cur_wind">with 3km/h SSW winds</span><hr class="hr_sm" /></td>' | sed -e 's/<[^>]*>//g'

输出

with 3km/h SSW winds

<强>解释

  • echo 'whatever'会将单词whatever回显到屏幕上(stdandard输出又名stdout)
  • |符号是管道。右边的命令将从echo获取输出并用它做一些事情
  • sed是流编辑器。它的-e开关告诉sed评估脚本或表达式
  • s/xyz/abc/g格式很简单。 s /意味着替代。 / g表示全局。用全局abc替换所有出现的xyz
  • s/<[^>]*>//g变得有趣。让我们关注<[^>]*>。这意味着,替换以&lt;开头的任何内容,不包含&gt;立即但包含任何其他字符,然后具有
  • 的<>
  • 例如,查看您的<span class="cur_wind">。该标签以&lt;开头,然后紧接着包含字符,然后有一个&gt;。 sed说,当找到这样的文本时,将其删除(替换为空)
  • <hr></td>使用相同的技巧。剩下的就是你想要的文字

这是一个有点简化的解释。

答案 2 :(得分:1)

grep不知道XML,因此是错误的工具;使用真正的XML解析器。从bash可以轻松访问的最好的一个是XMLStarlet

xmlstarlet sel -t -m "//span[@class='cur_wind']/text()" -v . -n <input.xml

这将提取直接包含在班级cur_wind范围内的所有文本。

答案 3 :(得分:0)

如果那就是你想要的那么猫| grep&#34;。 3km / h SSW风。&#34;应该这样做,但我怀疑还有更多你需要的东西