尝试使用 grep 从 HTML 文件中删除所有 ID

尝试使用 grep 从 HTML 文件中删除所有 ID

我正在尝试从文件id=" "中删除所有 s.html但我不确定哪里出错了。我尝试使用正则表达式,但我得到的只是.htmlUbuntu 终端中的文件渲染。

代码:

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表示仅打印匹配的模式。 (不是整条线)

sedawk通常用于编辑流或文件。例如,如上面的例子。


从你的 grep 有一些错误的概念:

 id\="[a-zA-Z][0-9]"

将完全匹配:

  1. id=
  2. 范围内的字符a-zA-Z
  3. 其次是个位数

换句话说,它将匹配:

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()会将内容放入其中htmlbody如果它尚未处于这样的结构中,它还会添加一个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>

相关内容