Jak parsować sto plików kodu źródłowego HTML w powłoce?


23

Mam kilkaset plików kodu źródłowego HTML. Muszę wyodrębnić zawartość określonego <div>elementu z każdego z tych plików, więc mam zamiar napisać skrypt, który przejdzie przez każdy plik. Struktura elementu wygląda następująco:

<div id='the_div_id'>
  <div id='some_other_div'>
  <h3>Some content</h3>
  </div>
</div>

Czy ktoś może zasugerować metodę, za pomocą której mogę wyodrębnić div the_div_idoraz wszystkie elementy potomne i zawartość z pliku przy użyciu wiersza polecenia systemu Linux?

Odpowiedzi:


27

Pakiet html-xml-utils , dostępny w większości głównych dystrybucji Linuksa, zawiera szereg narzędzi, które są użyteczne w przypadku dokumentów HTML i XML. Szczególnie przydatny w twoim przypadku jest to, że hxselectodczytuje ze standardowego wejścia i wyciąga elementy oparte na selektorach CSS. Twój przypadek użycia wyglądałby następująco:

hxselect '#the_div_id' <file

Możesz otrzymać skargę dotyczącą nieprawidłowego kształtowania danych wejściowych w zależności od tego, co je karmisz. Ta skarga dotyczy standardowego błędu i dlatego w razie potrzeby można ją łatwo zlikwidować. Alternatywą byłoby użycie pakietu HTML :: PARSER Perla; zostawię to jednak osobie z umiejętnościami Perla mniej zardzewiałymi niż moje własne.


1
hxselectjest bardziej wrażliwy na format wejściowy niż pup. Na przykład, ja dostaję Input is not well-formed. (Maybe try normalize?)z hxselect którym pupwłaśnie analizowania go.
AB

12

Wypróbuj pupnarzędzie wiersza polecenia do przetwarzania HTML. Na przykład:

pup '#the_div_id' < file.html

Terrrrrrrific!
CC

4

Oto nieprzetestowany skrypt Perla, który wyodrębnia <div id="the_div_id">elementy i ich zawartość za pomocą HTML::TreeBuilder.

#!/usr/bin/env perl
use strict;
use warnings;
use HTML::TreeBuilder;
foreach my $file_name (@ARGV) {
    my $tree = HTML::TreeBuilder->new;
    $tree->parse_file($file_name);
    for my $subtree ($tree->look_down(_tag => "div", id => "the_div_id")) {
        my $html = $subtree->as_HTML;
        $html =~ s/(?<!\n)\z/\n/;
        print $html;
    }
    $tree = $tree->delete;
}

Jeśli masz alergię na Perla, Python ma HTMLParser.

PS Nie próbuj używać wyrażeń regularnych. .



1

Oto Ex jeden wiersz, aby wyodrębnić tę część z każdego pliku:

ex -s +'bufdo!/<div.*id=.the_div_id/norm nvatdggdG"2p' +'bufdo!%p' -cqa! *.html

Aby zapisać / zamienić na miejscu, zmień sekcję -cqa!na -cxai usuń %p. W przypadku rekurencyjności rozważ użycie globbing ( **/*.html).

Zasadniczo dla każdego bufora / pliku ( bufdo) wykonuje następujące działania:

  • /pattern - znajdź wzór
  • norm - zacznij symulować normalne naciśnięcia klawiszy Vi
    • n - wskocz do następnego wzoru (wymagany w trybie Ex)
    • vatd- usuń wybraną sekcję zewnętrznego znacznika (patrz: przeskakiwanie między znacznikami HTML )
    • ggdG- usuń cały bufor (odpowiednik :%d)
    • "2p - ponownie wklej poprzednio usunięty tekst

Być może niezbyt wydajny i nie POSIX ( :bufdo), ale powinien działać.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.