Разбор HTML с помощью оболочки

У меня есть HTML с большим количеством данных и интересующей меня части:

<tr valign=top>
<td><b>Total</b></td>
<td align=right><b>54</b></td>
<td align=right><b>1</b></td>
<td align=right>0 (0/0)</td>
<td align=right><b>0</b></td>
</tr>

Я пытаюсь использовать awk который сейчас:

awk -F "</*b>|</td>" '/<[b]>.*[0-9]/ {print $1, $2, $3 }' "index.html"

но я хочу иметь:

54
1
0
0

Прямо сейчас я получаю:

'<td align=right> 54'
'<td align=right> 1'
'<td align=right> 0'

Какие-либо предложения?

Ответ 1

awk  -F '[<>]' '/<td / { gsub(/<b>/, ""); sub(/ .*/, "", $3); print $3 } ' file

Вывод:

54
1
0
0

Другой:

awk  -F '[<>]' '
/<td><b>Total<\/b><\/td>/ {
    while (getline > 0 && /<td /) {
        gsub(/<b>/, ""); sub(/ .*/, "", $3)
        print $3
    }
    exit
}' file

Ответ 2

awk не является парсером HTML. Используйте для этого xpath или даже xslt. xmllint - это инструмент командной строки, способный выполнять запросы XPath и xsltproc, который может использоваться для выполнения преобразований XSL. Оба инструмента принадлежат пакету libxml2-utils.

Также вы можете использовать язык программирования, способный анализировать HTML

Ответ 3

Вам действительно нужно использовать какой-то настоящий парсер HTML для этой работы, например:

perl -Mojo -0777 -nlE 'say [split(/\s/, $_->all_text)]->[0] for x($_)->find("td[align=right]")->each'

печатает:

54
1
0
0

Но для этого вам нужно иметь perl и установить Mojolicious package.

(его легко установить с помощью:)

curl -L get.mojolicio.us | sh

Ответ 4

$ awk -F'<td[^>]*>(<b>)?|(</?b>)?</td>' '$2~/[0-9]/{print $2+0}' file
54
1
0
0

Ответ 5

HTML-XML-utils

Вы можете использовать htmlutils для анализа хорошо отформатированных файлов HTML/XML. Пакет включает в себя множество бинарных инструментов для извлечения или изменения данных. Например:

$ curl -s http://example.com/ | hxselect title
<title>Example Domain</title>

Вот пример с предоставленными данными:

$ hxselect -c -s "\n" "td[align=right]" <file.html
<b>54</b>
<b>1</b>
0 (0/0)
<b>0</b>

Вот последний пример с удалением тегов <b>:

$ hxselect -c -s "\n" "td[align=right]" <file.html | sed "s/<[^>]\+>//g"
54
1
0 (0/0)
0

Для большего количества примеров, проверьте .

Ответ 6

BSD/GNU grep/ ripgrep

Для простого извлечения вы можете использовать grep, например:

  • Ваш пример использования grep:

    $ egrep -o "[0-9][^<]\?\+" file.html
    54
    1
    0 (0/0)
    0
    

    и используя ripgrep:

    $ rg -o ">([^>]+)<" -r '$1' <file.html | tail +2
    54
    1
    0 (0/0)
    0
    
  • Извлечение внешнего HTML H1:

    $ curl -s http://example.com/ | egrep -o '<h1>.*</h1>'
    <h1>Example Domain</h1>
    

Другие примеры:

  • Извлечение тела:

    $ curl -s http://example.com/ | xargs | egrep -o '<body>.*</body>'
    <body> <div> <h1>Example Domain</h1> ...
    

    Вместо xargs вы также можете использовать tr '\n' ' '.

  • Для нескольких тегов см.: Текст между двумя тегами.

Если вы имеете дело с большими наборами данных, рассмотрите возможность использования ripgrep который имеет похожий синтаксис, но намного быстрее, чем в Rust.

Ответ 7

ex/vim

Для более сложного анализа вы можете использовать встроенные редакторы, такие как ex/vi, где вы можете переключаться между соответствующими тегами HTML, выбирать/удалять внутренние/внешние теги и редактировать содержимое на месте.

Вот команда:

$ ex +"%s/^[^>].*>\([^<]\+\)<.*/\1/g" +"g/[a-zA-Z]/d" +%p -scq! file.html
54
1
0 (0/0)
0

Вот как работает команда:

  • Используйте ex -place редактор для замены во всех строках (%): ex +"%s/pattern/replace/g".

    Шаблон замещения состоит из 3 частей:

    • Выберите от начала строки до > (^[^>].*>) Для удаления, прямо перед 2-й частью.
    • Выберите нашу основную часть до < (([^<]+)).
    • Выберите все остальное после < для удаления (<.*).
    • Мы заменяем всю совпадающую строку на \1 которая ссылается на шаблон внутри скобок (()).
  • После подстановки мы удаляем любые буквенно-цифровые строки, используя global: g/[a-zA-Z]/d.

  • Наконец, напечатайте текущий буфер на экране с помощью +%p.
  • Затем молча (-s) выйти без сохранения (-c "q!") Или сохранить в файл (-c "wq").

При тестировании для замены файла на месте измените -scq! в -scwq.


Вот еще один простой пример, который удаляет тег стиля из заголовка и печатает проанализированный вывод:

$ curl -s http://example.com/ | ex -s +'/<style.*/norm nvatd' +%p -cq! /dev/stdin

Тем не менее, не рекомендуется использовать регулярные выражения для анализа вашего HTML, поэтому для долгосрочного подхода вы должны использовать соответствующий язык (например, Python, Perl или PHP DOM).


Смотрите также: