Regex 使用sed、grep或awk提取两个定位标记之间的文本 公元前480年,斯巴达国王列奥尼达斯和一支300人的军队在塞莫皮莱与波斯人作战。

Regex 使用sed、grep或awk提取两个定位标记之间的文本 公元前480年,斯巴达国王列奥尼达斯和一支300人的军队在塞莫皮莱与波斯人作战。,regex,bash,shell,awk,sed,Regex,Bash,Shell,Awk,Sed,我想提取两个div锚标记之间的文本。我是sed和awk的新手,所以我不知道怎么做。我尝试使用grep,但没有成功。正如Sundeep在评论中所说:最好使用合适的HTML解析器 标准实用程序大多基于行,对报价处理较差;他们不具备强大的解析HTML的能力,因为HTML在引用样式和空格方面存在各种变化,更不用说识别实际语法了 GNUgrep提供了比其他实现更大的灵活性:多行匹配(-z),支持PCREs(-p),支持查找断言 虽然以下GNUgrep命令可用于示例输入,但它仍然远远不是一个健壮的解析解决方

我想提取两个div锚标记之间的文本。我是sed和awk的新手,所以我不知道怎么做。我尝试使用grep,但没有成功。

正如Sundeep在评论中所说:最好使用合适的HTML解析器

标准实用程序大多基于行,对报价处理较差;他们不具备强大的解析HTML的能力,因为HTML在引用样式和空格方面存在各种变化,更不用说识别实际语法了

GNU
grep
提供了比其他实现更大的灵活性:多行匹配(
-z
),支持PCREs(
-p
),支持查找断言

虽然以下GNU
grep
命令可用于示例输入,但它仍然远远不是一个健壮的解析解决方案:

<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>
grep-zPo'\s*\K.*(?=\s*)文件

在Unix或类似Unix的终端上解析XML或HTML的推荐方法:

如果您正在寻找从unix命令行执行此操作的方法,我建议您首先考虑使用xml解析工具,而不是awk、grep或sed

例如,您的系统可能有。如果您的html包含在index.html文件中。以下xmllint命令用于提取文本:

 grep -zPo '<div class="summary_text" itemprop="description">\s*\K.*?(?=\s*</div>)' file
该命令后的文本需要修剪,因此您可能需要通过管道连接到另一个命令:

xmllint --html --xpath "//div[contains(@class, 'plot_summary')]/div[contains(@class, 'summary_text')]/text()" index.html
我们将输出输出到的sed命令有两个表达式。第一个删除行开头的空格/^[:space:]*/',第二个删除所有仅为空格的行'/^[:space:]*$/d'

您还可以研究其他xml命令行解析器工具(请参阅公认的答案):

使用sed的可怕方式:

通过使用echo将文件分成一行,可以绕过sed的逐行解析问题。然后使用sed替换可以提取所需的文本。这不是一个好方法,因为它是一个非常依赖格式的方法:

(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'
(set-o noglob;echo$(cat index.html))\

|sed的/*]*类[^=]*=[^”]*=“summary_text”[^>]*>[[:space:]]*\([^添加您尝试过的grep命令,它将显示您尝试过一些东西……此外,这最适合html parserIt。parserIt给出了一个错误,对它进行了一点grep-zPo'\s*\K.*(?=\s*)”修改,它成功了!谢谢:D@SwastikUdupa:很高兴听到它起作用;re error:有趣-我没有一个(GNU grep v2.22),但您的调整是最简单的解决方案,因此我已经用它更新了答案。++用于演示正确的解决方案。鉴于输入是HTML,而不是XML,您可能应该使用
xmllint--HTML
。在大多数情况下,规范化为单行的方法可能很好,除了
echo$(cat…)
是一个坏主意,因为文件中的令牌要进行全局绑定。避免此问题的一个足够好的近似方法是
tr-s'[:space:]'
;作为这个空白规范化步骤的替代方法,您可以在
sed
本身中循环构建整个输入,在GNU
sed
的情况下,只需使用
-z
。很棒的评论!对我来说有很多学习内容。喜欢它:)。当我在电脑前时,我会更新我的答案,并能消化所有内容。在这里的OSX上。我开始认为我应该研究获取我最喜欢的命令的GNU副本。+++你也是这样。干杯@mklement0很高兴听到这个消息,谢谢你。是的,使用GNU实用程序的生活要容易得多,但重要的是要知道什么是GNU特定的,什么不是dea我之前的评论的附录:
(set-f;echo$(cat index.html))
是一个实用的解决方案,可以解决不需要的全局搜索问题(请注意,封闭的子shell可以本地化
set-f
)的效果。很漂亮!你知道我在这里经常看到这些类型的问题。“我的sed/grep没有正确解析我的html。”“问题。前几天回答了一个类似的问题。我甚至在过去自己写过这样的解决方案来刮网站。(现在我会做不同的事情)。如果尚未添加到堆栈溢出文档中,似乎是一件好事;从命令行解析xml、HTML和JSON的最佳方法和工具。@mklement0I没有看到与我在堆栈溢出文档中建议的内容类似的内容。现在有一个问题需要思考和思考。这个主题应该放在Bash、Unix或命令行标记下吗。Ha我想这是一个……有什么想法或意见@mklement0?
(set -o noglob; echo $(cat index.html)) \
| sed 's/.*<div[^>]*class[^=]*=[^"]*"summary_text"[^>]*>[[:space:]]*\([^<]*\).*/\1/'