Извлекать текст из тегов html с определенным идентификатором, используя sed или grep

Какую команду я должен использовать для извлечения текста из следующего HTML-кода, который находится в файле "test.html", содержащем: "<span id="imAnID">extractme</span>"?

Файл будет больше, поэтому мне нужно указать grep или sed на id, а затем сказать ему, чтобы он извлекал только текст из тега с таким идентификатором. Предполагая, что я запускаю терминал из каталога, в котором находится файл, я делаю это:

cat test.html | sed -n 's/.*<span id="imAnID">\(.*\)<\/span>.*/\1/p'

Что я делаю неправильно? Я получаю пустой вывод... Не против использования grep для этого, если это проще.

4 ответа

Для этого неудобно использовать awk, sed или grep, поскольку эти инструменты основаны на строках (по одной строке за раз). Гарантируется ли, что интервал, который вы пытаетесь извлечь, находится на одной линии? Есть ли возможность использования других тегов в пределах диапазона (например, em теги)? Если нет, то это звучит как работа для Perl.

awk, sed и grep являются линейно-ориентированными инструментами. XML и HTML основаны на тегах. Они не очень хорошо сочетаются друг с другом, хотя вы можете обойтись с помощью awk, sed и grep в XML и HTML, используя симпатичные средства форматирования в XML или HTML, прежде чем прибегать к своим линейно-ориентированным инструментам.

Существует программа под названием xmlgawk, которая должна быть похожа на gawk, но все еще работает с XML.

Лично я предпочитаю делать такие вещи в Python, используя модуль lxml, чтобы XML/HTML мог быть полностью понят, не становясь слишком многословным.

С помощью grep -o

echo "<span id="imAnID" hello>extractme</span> <span id='imAnID'>extractmetoo</span>" | grep -oE 'id=.?imAnID[^<>]*>[^<>]+' | cut -d'>' -f2

найду:

#=>extractme
#=>extractmetoo

это будет работать, если span элемент, несущий желаемое id атрибут приходит непосредственно перед extractme вещи.

Вы можете попробовать сделать это с awk вместо:

  #!/bin/bash

  start_tag="span id=\"imAnID\""
  end_tag="/span"

  awk -F'[<>]' -v taga="$start_tag" -v tagb="$end_tag" '{ i=1; while (i<=NF) { if ($(i)==taga && $(i+2)==tagb) { print $(i+1) }; i++} }'

Используйте это:

$ ./script < infile > outfile
Другие вопросы по тегам