使用sed,grep或awk提取两个锚标记之间的文本
<div class="plot_summary minPlotHeightWithPoster">
<div class="summary_text" itemprop="description">
King Leonidas of Sparta and a force of 300 men fight the Persians at Thermopylae in 480 B.C.
</div>
我想提取两个div锚标记之间的文本。我是sed和awk的新手,所以我无法弄清楚如何做到这一点。我尝试使用grep,但它不成功。使用sed,grep或awk提取两个锚标记之间的文本
由于Sundeep在评论中指出:最好使用合适的HTML解析器。
标准公用事业主要是行为基础,并与引用欠佳;他们没有足够的能力来强大地解析HTML,所有的变化都围绕着引用样式和空白,更不用说承认实际的语法了。
GNUgrep
提供了比其它实施方式中更大的灵活性:多线匹配(-z
),支持PCREs(-P
),这使得能够环视断言。
虽然下面的GNU grep
命令作品与样品输入,它仍然是远不是一个强大的解析溶液:
grep -zPo '<div class="summary_text" itemprop="description">\s*\K.*?(?=\s*</div>)' file
非常感谢!:) –
它给了一个错误,修改了一下grep -zPo'
@SwastikUdupa:很高兴听到它的工作;重新错误:有趣 - 我没有得到一个(GNU grep v2.22),但是你的调整是更简单的解决方案,所以我已经用它更新了答案。 – mklement0
推荐方法在Unix或类Unix终端解析XML或HTML:
如果您正在寻找一种方法从unix命令行执行此操作,我建议首先考虑使用xml解析工具而不是awk,grep或sed。
例如,您的系统可能有xmllint。如果你的html包含在文件index.html中。下面xmllint命令的工作来提取文本:
xmllint --html --xpath "//div[contains(@class, 'plot_summary')]/div[contains(@class, 'summary_text')]/text()" index.html
文本需要一个命令后,修剪所以你可能管到另一个命令做到这一点:
(xpath="//div[contains(@class, 'plot_summary')]/div[contains(@class, 'summary_text')]/text()" && \
xmllint --html --xpath "$xpath" index.html) \
| sed -e 's/^[[:space:]]*//' -e '/^[[:space:]]*$/d'
这sed的命令,我们一举超越输出有两个表达式。第一个在该行's/^[[:space:]]*//'
的开始删除空白和第二删除该只是空白的任何行'/^[[:space:]]*$/d'
有你可以研究(见接受的答案)其他XML命令行分析器工具: How to execute XPath one-liners from shell?
使用sed的可怕方法:
您可以通过使用echo将文件分解成一行来解决sed的分析问题。然后使用sed替换你可以提取你想要的文本。这不是一个很好的方法,因为它是一个非常格式相关方法:
(set -o noglob; echo $(cat index.html)) \
| sed 's/.*<div[^>]*class[^=]*=[^"]*"summary_text"[^>]*>[[:space:]]*\([^<]*\).*/\1/'
更新通过set command
++用于演示适当的解决方案。鉴于输入是HTML,而不是XML,你应该使用'xmllint --html'。 在大多数情况下,normalize-to-single-line-beforehand方法可能没有问题,只不过'echo $(cat ...)'是一个坏主意, 因为文件中的标记受_globbing_支配。避免这个问题的一个足够好的近似值是'tr -s'[:space:]''''; 作为这个空白标准化步骤的替代方法,您可以循环在'sed'本身内建立整个输入,并且在_GNU_'sed'的情况下只需使用'-z'。 – mklement0
很好的评论!很多在那里为我学习。爱它 :)。当我在电脑上时,我会更新我的答案,并且可以将它们全部消化。在OSX上。开始认为我应该研究获取我最喜爱的命令的GNU副本。 ++也是你的方式。欢呼@ mklement0 –
很高兴听到它,并感谢你。是的,使用GNU工具的生活要容易得多,但重要的是要知道什么是GNU特有的,什么不是在与其他平台打交道时。我以前的评论的补充:'(set -f; echo $(cat index.html))'是解决不必要的globbing问题的实用解决方案(注意包围子shell来定位'set -f'的效果)。 – mklement0
禁用globbing每mklement0的评论加你试图grep命令,它会告诉你已经尝试过的东西...此外,这是最适合HTML解析器 – Sundeep