Tentando remover todos os ids de um arquivo HTML com grep

2

Estou tentando remover todos os id=" " s de um arquivo .html , mas não tenho certeza de onde estou indo errado. Eu tentei usar expressões regulares, mas tudo o que estou recebendo é a renderização do arquivo .html no meu terminal Ubuntu.

Código:

grep -Ev '^$id\="[a-zA-Z][0-9]"' *.html

Estou executando com bash ex.sh .

    
por DᴀʀᴛʜVᴀᴅᴇʀ 18.04.2013 / 18:30

3 respostas

9

Embora isso vá contra o meu melhor julgamento, vou postá-lo ( sed part).

Isto é: se for por uma solução rápida e suja, vá em frente. Se for um pouco mais sério ou algo que você vai fazer com freqüência etc. Use outra coisa como python, perl etc., onde você não depende de expressões regulares, mas de módulos para manipular documentos HTML.

Uma das maneiras mais simples seria usar, e. sed.

sed 's/\(<[^>]*\) \+id="[^"]*"\([^>]*>\)//' sample.html > noid.html

Explicado:

            +--------------------------------- Match group 1
            |                      +---------- Match group 2
         ___|___                ___|___
        |       |              |       |  
sed 's/\(<[^>]*\) \+id="[^"]*"\([^>]*>\)//' sample.html > noid.html
     |   |  | |   |  |    | ||    |  |      |
     |   |  | |   |  |    | ||    |  |      +-   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

Use sed -i para editar o arquivo no lugar. (Lamenta possível, mas não desfazer.)

Melhor; exemplo usando 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;
}

Seu comando grep não corresponderia a nada. Mas como você usa a opção invertida -v it imprime tudo que não corresponde - assim, o arquivo inteiro.

O grep não é um modificador de arquivos no local , mas normalmente é uma ferramenta para encontrar coisas em arquivo (s). Tente, por exemplo:

grep -o '\(<[^>]*\)id="[^"]*"[^>]*>' sample.html

-o significa imprimir apenas o padrão de correspondência. (Não linha inteira)

sed , awk etc. são geralmente usados para editar fluxos ou arquivos. Por exemplo. como pelo exemplo acima.

Do seu grep há algumas concepções erradas:

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

Corresponderia exatamente:

  1. id=
  2. Um caractere no intervalo a-z ou A-Z
  3. Seguido por um dígito único

Em outras palavras, corresponderia:

id="a0"
id="a1"
id="a2"
...
id="Z9"

Nada como: id="foo99" ou id="blah-gah" .

Além disso, corresponderia:

 ^ <-- 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)

Assim, nada.

    
por 18.04.2013 / 20:27
1

Eu não estou sugerindo isso seriamente, mas resolvi como fazer isso com um processador XSLT que aceita html. Executar com 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>
    
por 18.04.2013 / 22:38
0

Como mencionado em outra resposta , você pode usar um one-liner Ruby para analisar HTML. Por exemplo, você pode usar o seguinte:

ruby -rnokogiri -e 'doc = Nokogiri::HTML(readlines.join); doc.xpath("//@id").remove; puts doc' sample.html

Esta linha analisa o arquivo fornecido como argumento, sample.html, remove todos os atributos id e imprime a saída. Se sample.html for

<!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>

gera

<!DOCTYPE html>
<html><body>
    <h2>Section 1</h2>
    <h2>Section 3</h2>
    <h2>Section 4</h2>
    <h2>Section 5</h2>
  </body></html>

Observe que usar Nokogiri::HTML() colocará o conteúdo dentro de html e body se ainda não estiver em tal estrutura e também adicionará DOCTYPE . Se você quiser remover html , body e DOCTYPE ou não desejar adicioná-los, use

ruby -rnokogiri -e 'doc = Nokogiri::HTML.fragment(readlines.join); doc.search("@id").remove; puts doc' sample.html

que para o mesmo arquivo de entrada será produzido

    <h2>Section 1</h2>
    <h2>Section 3</h2>
    <h2>Section 4</h2>
    <h2>Section 5</h2>
    
por 18.04.2013 / 21:53