シェルを使用してHTMLをテーブルに変換する方法

シェルを使用してHTMLをテーブルに変換する方法

コンテンツが比較的単純で一貫した形式で保持される何百ものHTMLファイルがあります。

これをテーブルに変換する必要があります。これにシェルスクリプトを使用できますか?

HTMLソースコード

<html>
<head>
<title>Demo</title>
</head>
<body>
    <h1>Page Title</h1>
    <div class="row">
        <p class="text-1">Text 1</p>
        <p class="text-2">Text 2</p>
        <p class="text-3">Text 3</p>
        <p class="text-4">Text 4</p>
        <p class="text-5">Text 5</p>
        <p class="text-6">Text 6</p>
    </div>
    <div class="row">
        <p class="text-1">Text 1</p>
        <p class="text-2">Text 2</p>
        <p class="text-3">Text 3</p>
        <p class="text-4">Text 4</p>
        <p class="text-5">Text 5</p>
        <p class="text-6">Text 6</p>
    </div>
    <div class="row">
        <p class="text-1">Text 1</p>
        <p class="text-2">Text 2</p>
        <p class="text-3">Text 3</p>
        <p class="text-4">Text 4</p>
        <p class="text-5">Text 5</p>
        <p class="text-6">Text 6</p>
    </div>
</body>
</html>

変換表のソースコード

<table>
    <caption>Page Title</caption>
    <thead>
        <tr>
            <th>Hard Code</th>
            <th>Hard Code</th>
            <th>Hard Code</th>
            <th>Hard Code</th>
            <th>Hard Code</th>
            <th>Hard Code</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Text 1</td>
            <td>Text 2</td>
            <td>Text 3</td>
            <td>Text 4</td>
            <td>Text 5</td>
            <td>Text 6</td>
        </tr>
        <tr>
            <td>Text 1</td>
            <td>Text 2</td>
            <td>Text 3</td>
            <td>Text 4</td>
            <td>Text 5</td>
            <td>Text 6</td>
        </tr>
        <tr>
            <td>Text 1</td>
            <td>Text 2</td>
            <td>Text 3</td>
            <td>Text 4</td>
            <td>Text 5</td>
            <td>Text 6</td>
        </tr>
    </tbody>
</table>

これがマインドマップです。

ここに画像の説明を入力してください。

質問をする前に、オンラインで情報を閲覧したところ、次のコマンドを使用するとHTMLコンテンツを抽出できることがわかりました。子犬ツール、使用法は次のとおりです。

# Extracting page titles
cat demo.html | pup 'body > h1 text{}'

# Extracting paragraph text
cat demo.html | pup 'body > div.row > p.text-1 text{}'
cat demo.html | pup 'body > div.row > p.text-2 text{}'
cat demo.html | pup 'body > div.row > p.text-3 text{}'
cat demo.html | pup 'body > div.row > p.text-4 text{}'
cat demo.html | pup 'body > div.row > p.text-5 text{}'
cat demo.html | pup 'body > div.row > p.text-6 text{}'

次に、私は困難に遭遇し、これをシェルスクリプトにする方法を知りませんでした。これにはシェルループが含まれており、成功せずにそれを見つけようと数日を過ごしました。

みんな私を助けてもらえますか?よろしくお願いします!

修正する

それが私がやろうとしていることです。いくつかの問題があります。

  • これは1つのデータしか処理できません。<div class="row">...</div>これは私が経験した最も困難な問題です(以下に示す問題)。これにはシェルループの問題が含まれます。 ここに画像の説明を入力してください。
  • 一度に1つのHTMLファイルのみを変換でき、理想的には何百ものHTMLファイルをバッチ処理できます(別のディレクトリにエクスポートしてファイル名を一貫して保存します)。
#!/usr/bin/env bash

# Extracts HTML content
page_title=$(cat demo.html | pup 'body > h1 text{}')
paragraph_text_a=$(cat demo.html | pup 'body > div.row > p.text-1 text{}')
paragraph_text_b=$(cat demo.html | pup 'body > div.row > p.text-2 text{}')
paragraph_text_c=$(cat demo.html | pup 'body > div.row > p.text-3 text{}')
paragraph_text_d=$(cat demo.html | pup 'body > div.row > p.text-4 text{}')
paragraph_text_e=$(cat demo.html | pup 'body > div.row > p.text-5 text{}')
paragraph_text_f=$(cat demo.html | pup 'body > div.row > p.text-6 text{}')

# Print the contents in a predetermined format
cat << EOF
<table>
    <caption>$page_title</caption>
    <thead>
        <tr>
            <th>Hard Code</th>
            <th>Hard Code</th>
            <th>Hard Code</th>
            <th>Hard Code</th>
            <th>Hard Code</th>
            <th>Hard Code</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>$paragraph_text_a</td>
            <td>$paragraph_text_b</td>
            <td>$paragraph_text_c</td>
            <td>$paragraph_text_d</td>
            <td>$paragraph_text_e</td>
            <td>$paragraph_text_f</td>
        </tr>
    </tbody>
</table>
EOF

ベストアンサー1

以下はある程度トリックを行う必要があります。私を覚えてください。

  • テストせずに書いた。編集:これでテストしていくつかのバグを修正したので、うまくいくようです。
  • 私は極端な場合(複数<h1><tbody>テーブルフィールド内など...)を無視します。

「scriptname.pl」に入れて、2行目と3行目のファイル名を変更して実行してください。perl scriptname.pl

#!/usr/bin/perl
open my $ifh, "inputfilename.html";
open my $ofh, ">outputfilename.html";
while(<$ifh>) {
  if(/<h1>(.*)<\/h1>/) {
    my $header = << "END";
  <table>
    <caption>$1</caption>
    <thead>
        <tr>
            <th>Hard Code</th>
            <th>Hard Code</th>
            <th>Hard Code</th>
            <th>Hard Code</th>
            <th>Hard Code</th>
            <th>Hard Code</th>
        </tr>
    </thead>
    <tbody>
END
    print $ofh $header;
  } elsif(/<div class="row">/) {
    print $ofh "<tr>\n";
  } elsif(/<\/div>/) {
    print $ofh "</tr>\n";
  } elsif(/<p class=".*?">(.*)<\/p>/) {
    print $ofh "<td>$1</td>\n";
  } elsif(/<\/body>/) {
    print $ofh "</tbody>\n</table>\n</body>\n";
  } else {
    print $ofh $_;
  }
}
close $ofh;
close $ifh;

おすすめ記事