我正在尝试从文件id=" "
中删除所有 s.html
但我不确定哪里出错了。我尝试使用正则表达式,但我得到的只是.html
Ubuntu 终端中的文件渲染。
代码:
grep -Ev '^$id\="[a-zA-Z][0-9]"' *.html
我正在用 执行它bash ex.sh
。
答案1
尽管这违背了我更好的判断,但我会将其发布(sed
部分)。
也就是说:如果是为了快速而肮脏的修复,那就继续吧。如果是更严重的事情或者你要经常做的事情等等。使用其他的东西,比如 python、perl 等,你不依赖正则表达式,而是依赖模块来处理 HTML 文档。
一种更简单的方法是使用例如 sed。
sed 's/\(<[^>]*\) \+id="[^"]*"\([^>]*>\)/\1\2/' sample.html > noid.html
解释:
+--------------------------------- Match group 1
| +---------- Match group 2
___|___ ___|___
| | | |
sed 's/\(<[^>]*\) \+id="[^"]*"\([^>]*>\)/\1\2/' sample.html > noid.html
| | | | | | | || | | |
| | | | | | | || | | +- \1\2 Subst. with group 1 and 2
| | | | | | | || | +-------- > Closing bracket
| | | | | | | || +----------- [^>]* Same as below
| | | | | | | |+---------------- " Followed by "
| | | | | | | +----------------- * Zero or more times
| | | | | | +------------------- [^"] Not double-quote
| | | | | +------------------------ id=" Literal string
| | | | +--------------------------- \+ Space 1 or more times
| | | +------------------------------- * Zero or more times
| | +--------------------------------- [^>] Not closing bracket
| +------------------------------------ < Opening bracket
+---------------------------------------- s Substitute
用于sed -i
就地编辑文件。 (可能会后悔,但无法挽回。)
更好的;使用 perl 的示例:
#!/usr/bin/perl
use strict;
use warnings;
use HTML::TokeParser::Simple;
use HTML::Entities;
use utf8;
die "$0 [file]\n" unless defined $ARGV[0];
my $parser = HTML::TokeParser::Simple->new(file => $ARGV[0]);
if (!$parser) {
die "No HTML file found.\n";
}
while (my $token = $parser->get_token) {
$token->delete_attr('id');
print $token->as_is;
}
您的 grep 命令不会匹配任何内容。但是当您使用反转选项时,-v
它会打印所有不匹配的内容 - 从而打印整个文件。
grep 不是就地文件修改器但通常是在文件中查找内容的工具。尝试例如:
grep -o '\(<[^>]*\)id="[^"]*"[^>]*>' sample.html
-o
表示仅打印匹配的模式。 (不是整条线)
sed
等awk
通常用于编辑流或文件。例如,如上面的例子。
从你的 grep 有一些错误的概念:
id\="[a-zA-Z][0-9]"
将完全匹配:
id=
- 一范围内的字符
a-z
或A-Z
- 其次是一个位数
换句话说,它将匹配:
id="a0"
id="a1"
id="a2"
...
id="Z9"
没有什么像:id="foo99"
或id="blah-gah"
。
此外,它会匹配:
^ <-- start of line (As it is first in pattern or group)
$ <-- end of line (As you use the `-E` option)
# Else it would be:
^ <-- start of line (As it is first in pattern or group)
$ <-- dollar sign (Does not mean end of line unless it is at end of
pattern or group)
因此什么也没有。
答案2
我并不是认真地建议这样做,但我研究了如何使用接受 html 的 XSLT 处理器来做到这一点。运行与xsltproc --html strip-html-id.xslt input.html
<!-- strip-html-id.xslt -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" doctype-system="about:legacy-compat" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@id" />
</xsl:stylesheet>
答案3
正如中提到的另一个答案您可以使用 Ruby one-liner 来解析 HTML。例如,您可以使用以下内容:
ruby -rnokogiri -e 'doc = Nokogiri::HTML(readlines.join); doc.xpath("//@id").remove; puts doc' sample.html
此行解析作为参数给出的文件,sample.html,剥离它的所有id
属性并打印输出。如果sample.html是
<!DOCTYPE html>
<html>
<body>
<h2 id="section1">Section 1</h2>
<h2 id="section2">Section 3</h2>
<h2>Section 4</h2>
<h2 id="section5">Section 5</h2>
</body>
</html>
它输出
<!DOCTYPE html>
<html><body>
<h2>Section 1</h2>
<h2>Section 3</h2>
<h2>Section 4</h2>
<h2>Section 5</h2>
</body></html>
请注意,通过使用Nokogiri::HTML()
会将内容放入其中html
,body
如果它尚未处于这样的结构中,它还会添加一个DOCTYPE
.如果您想删除html
或不希望添加它们,您可以body
使用DOCTYPE
ruby -rnokogiri -e 'doc = Nokogiri::HTML.fragment(readlines.join); doc.search("@id").remove; puts doc' sample.html
对于相同的输入文件将输出
<h2>Section 1</h2>
<h2>Section 3</h2>
<h2>Section 4</h2>
<h2>Section 5</h2>