web-dev-qa-db-ja.com

シェルで100のhtmlソースコードファイルを解析する方法

私は数百のhtmlソースコードファイルを持っています。これらの各ファイルから特定の<div>要素のコンテンツを抽出する必要があるので、各ファイルをループするスクリプトを記述します。要素の構造は次のとおりです。

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

Linuxのコマンドラインを使用して、div the_div_idとすべての子要素とコンテンツをファイルから抽出する方法を誰かが提案できますか?

23
conorgriffin

ほとんどの主要なLinuxディストリビューションで利用可能な html-xml-utils パッケージには、HTMLおよびXMLドキュメントを処理するときに役立つツールがいくつかあります。 hxselectは、標準入力から読み取り、CSSセレクターに基づいて要素を抽出する場合に特に便利です。ユースケースは次のようになります。

hxselect '#the_div_id' <file

入力する内容によっては、入力が適切に形成されていないという不満が出る場合があります。この苦情は標準エラーに対して与えられるため、必要に応じて簡単に抑制できます。これに代わる方法は、PerlのHTML :: PARSERパッケージを使用することです。ただし、Perlのスキルを持っていて、自分よりもさびが少ない人に任せます。

28
Steven D

HTMLを処理するためのコマンドラインツール pup を試してください。例えば:

pup '#the_div_id' < file.html
13
Trevor Dixon

<div id="the_div_id"> を使用してHTML::TreeBuilder要素とその内容を抽出するテストされていないPerlスクリプトを次に示します。

#!/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;
}

Perlにアレルギーがある場合、Pythonには HTMLParser があります。

追伸 正規表現を使用しないでください。

以下は、各ファイルからその部分を抽出するEx one-linerです。

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

インプレースで保存/置換するには、-cqa!-cxaに変更し、%pセクションを削除します。再帰性については、グロビング(**/*.html)の使用を検討してください。

基本的には、各バッファー/ファイル(bufdo)に対して、次のアクションを実行します。

  • /pattern-パターンを見つける
  • norm-通常のViキーストロークのシミュレーションを開始します
    • n-次のパターンにジャンプします(Exモードで必要)
    • vatd-選択した外部タグセクションを削除します(参照: htmlタグ間のジャンプ
    • ggdG-バッファー全体を削除します(:%dと同等)
    • "2p-以前に削除したテキストを再貼り付け

多分あまり効率的ではなく [〜#〜] posix [〜#〜]:bufdo)ですが、動作するはずです。

1
kenorb