Comment analyser une centaine de fichiers de code source html dans le shell?

23

J'ai quelques centaines de fichiers de code source html. J'ai besoin d'extraire le contenu d'un <div>élément particulier de chacun de ces fichiers, donc je vais écrire un script pour parcourir chaque fichier. La structure de l'élément est la suivante:

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

Quelqu'un peut-il suggérer une méthode par laquelle je peux extraire le div the_div_idet tous les éléments enfants et le contenu d'un fichier en utilisant la ligne de commande linux?

conorgriffin
la source

Réponses:

27

Le paquet html-xml-utils , disponible dans la plupart des principales distributions Linux, possède un certain nombre d'outils utiles pour traiter des documents HTML et XML. Particulièrement utile pour votre cas est la hxselectlecture à partir d'une entrée standard et l'extraction d'éléments basés sur des sélecteurs CSS. Votre cas d'utilisation ressemblerait à:

hxselect '#the_div_id' <file

Vous pourriez recevoir une plainte concernant la mauvaise formation des intrants en fonction de ce que vous l'alimentez. Cette plainte concerne l'erreur standard et peut donc être facilement supprimée si nécessaire. Une alternative à ceci serait d'utiliser le package HTML :: PARSER de Perl; cependant, je laisserai cela à quelqu'un avec des compétences en Perl moins rouillé que le mien.

Steven D
la source
1
hxselectest plus pointilleux sur le format d'entrée que pup. Par exemple, je reçois Input is not well-formed. (Maybe try normalize?)avec hxselectpupvient l' analyser.
AB
12

Essayez pup, un outil en ligne de commande pour le traitement HTML. Par exemple:

pup '#the_div_id' < file.html
Trevor Dixon
la source
Terrrrrrrific!
CC
4

Voici un script Perl non testé qui extrait les <div id="the_div_id">éléments et leur contenu à l'aide 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;
}

Si vous êtes allergique à Perl, Python en a HTMLParser.

PS N'essayez pas d'utiliser des expressions régulières. .

Gilles 'SO- arrête d'être méchant'
la source
1

Voici Ex one-liner pour extraire cette partie de chaque fichier:

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

Pour enregistrer / remplacer sur place, passez -cqa!à -cxaet supprimez la %psection. Pour la récursivité, envisagez d'utiliser globbing ( **/*.html).

Fondamentalement, pour chaque tampon / fichier ( bufdo), il effectue les actions suivantes:

  • /pattern - trouver le motif
  • norm - commencer à simuler les frappes Vi normales
    • n - passer au motif suivant (requis en mode Ex)
    • vatd- supprimer la section de balise externe sélectionnée (voir: sauter entre les balises html )
    • ggdG- supprimer tout le tampon (équivalent à :%d)
    • "2p - recollez le texte précédemment supprimé

Peut-être pas très efficace et pas POSIX ( :bufdo), mais cela devrait fonctionner.

kenorb
la source
note bufdo n'est pas POSIX pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
Steven Penny