Попытка удалить все идентификаторы из файла HTML с grep

Я предполагаю, что Ваша секунда "по линии" dest из входного файла, который содержит значения, которые Вы проверяете по исключенным значениям (например, называете этот входной файл "данными").
Можно читать в списке исключенных значений через другой файл (например, названный "исключают"). Если исключают, уже разграничен |, просто используйте sed для изменения их на \n.

Создайте тестовые файлы

sed 's/ /\n/g' <<<"blah1 blah2 abcde" >data
sed 's/|/\n/g' <<<"blah1|blah2|blah3" >exclude

Сценарий

awk '{
  if( NR==FNR ) { exclude[$0]++ 
  }else{ 

    # somewhere later on
    # "dest" to be tested is $1 of "data"
    if( exclude[$1] ) print "do something", $1 
  }
}' exclude data

или что-то вроде этого для передачи этих 2 "файлов" может подойти.:

}' <(sed 's/|/\n/g' <<<"blah1|blah2|blah3") \
   data  

Вывод

do something blah1
do something blah2
2
10.06.2013, 09:24
3 ответа

Хотя это идет вразрез с моим лучшим суждением, я отправлю его (sed часть).

Это: если это для быстрого и грязного разрешения фиксации. Если это немного более серьезно или что-то, что Вы собираетесь сделать часто и т.д. Используйте что-то еще как Python, жемчуг и т.д., где Вы не полагаетесь на регулярные выражения, а скорее модули для обработки документов 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 отредактировать файл на месте. (Сожалеет возможный, но никакая отмена.)


Лучше; пример с помощью жемчуга:

#!/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]"

Соответствовал бы точно:

  1. id=
  2. Один символ в диапазоне a-z или A-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)

Таким образом ничто.

8
27.01.2020, 21:51
  • 1
    , это является потрясающим! –  DᴀʀᴛʜVᴀᴅᴇʀ 18.04.2013, 22:29

Я серьезно не предлагаю это, но я разработал, как сделать это с процессором XSLT, который принимает HTML. Выполненный с 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>
1
27.01.2020, 21:51

Как упомянуто в другом ответе можно использовать остроту Ruby для парсинга 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 если это уже не находится в такой структуре, и это также добавит a 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>
0
27.01.2020, 21:51
  • 1
    Является там ошибкой в этом? Это полосы DOCTYPE, head и т.д. и вставленный во все это body тег. Это также переформатировало документ. –  Runium 18.04.2013, 23:28
  • 2
    @Sukminder я сделал редактирование вскоре после того, как я отправил. Теперь это ни во что не переносит его. –  N.N. 19.04.2013, 08:02
  • 3
    Спасибо за обратную связь, но это с Вашей текущей строкой. Спецификация: ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux], Nokogiri (1.5.5). Выполнил его на HTML для этого сайта. (Как в этом: unix.stackexchange.com/questions/72917 / …) –  Runium 19.04.2013, 17:22
  • 4
    @Sukminder я отредактировал для показа различия parse и fragment. –  N.N. 19.04.2013, 17:42
  • 5
    , если <body> теги находятся в столбце 1 (никакое пространство перед ним на строке) – это не разделяется с помощью fragment. Если существует пространство или вкладка и т.д. перед ним затем, это. Это также перемещает такие вещи как meta, заголовок, ссылка на CSS и JavaScript вниз для полимеризации при отсутствии разделения. Вот образец. –  Runium 19.04.2013, 18:24

Теги

Похожие вопросы