我有几百个 html 源代码文件。我需要从每个文件中提取特定元素的内容<div>
,因此我将编写一个脚本来循环访问每个文件。元素结构是这样的:
<div id='the_div_id'>
<div id='some_other_div'>
<h3>Some content</h3>
</div>
</div>
the_div_id
谁能建议一种方法,让我可以使用 Linux 命令行从文件中提取 div以及所有子元素和内容?
答案1
这html-xml-utils大多数主要 Linux 发行版中都提供了该软件包,其中包含许多在处理 HTML 和 XML 文档时非常有用的工具。对您的情况特别有用的是hxselect
它从标准输入读取并基于 CSS 选择器提取元素。您的用例如下所示:
hxselect '#the_div_id' <file
您可能会收到关于输入格式不正确的抱怨,具体取决于您提供的内容。此投诉是针对标准错误给出的,因此如果需要,可以轻松抑制。另一种方法是使用 Perl 的 HTML::PARSER 包;然而,我会把这个任务留给 Perl 技能比我不那么生疏的人。
答案2
尝试pup
,一个用于处理 HTML 的命令行工具。例如:
pup '#the_div_id' < file.html
答案3
这是一个未经测试的 Perl 脚本,它<div id="the_div_id">
使用以下命令提取元素及其内容HTML::TreeBuilder
。
#!/usr/bin/env perl
use strict;
use warnings;
use HTML::TreeBuilder;
foreach my $file_name (@ARGV) {
my $tree = HTML::TreeBuilder->new;
$tree->parse_file($file_name);
for my $subtree ($tree->look_down(_tag => "div", id => "the_div_id")) {
my $html = $subtree->as_HTML;
$html =~ s/(?<!\n)\z/\n/;
print $html;
}
$tree = $tree->delete;
}
如果你对 Perl 过敏,Python 有HTMLParser
。
聚苯乙烯不要尝试使用正则表达式。。
答案4
这是从每个文件中提取该部分的前一行:
ex -s +'bufdo!/<div.*id=.the_div_id/norm nvatdggdG"2p' +'bufdo!%p' -cqa! *.html
要就地保存/替换,请更改-cqa!
为-cxa
并删除%p
部分。对于递归性,请考虑使用通配符 ( **/*.html
)。
它基本上对于每个缓冲区/文件(bufdo
),它执行以下操作:
/pattern
- 找到模式norm
- 开始模拟正常的 Vi 击键n
- 跳到下一个模式(Ex模式下需要)vatd
- 删除选定的外部标签部分(请参阅:在 html 标签之间跳转)ggdG
- 删除整个缓冲区(相当于:%d
)"2p
- 重新粘贴之前删除的文本
也许效率不是很高,也不是POSIX( :bufdo
),但应该可以。