Как использовать оболочку для преобразования HTML в таблицу

Довольно просто:

$ ping -c 1 -W 3 www.go.org | grep -q "100% packet loss" && echo "Packet loss" || echo "Packet received"
2
18.08.2020, 12:41
2 ответа

Вы пытаетесь извлечь ячейку за ячейкой, что затруднит перестроение таблицы.

Использование только простых bashи pup:

#!/bin/bash

count=$(grep '<div ' demo.html | wc -l)
page_title=$(cat demo.html | pup 'body h1 text{}')

tbody() {
    for ((i=1;i<count+1;++i)); do
        IFS=, row=$(cat demo.html | pup "body div.row:nth-of-type($i) text{}" | grep '\S' | paste -s -d, -)
        printf "\t\t<tr>\n"
        printf '\t\t\t<td>%s</td>\n' $row
        printf "\t\t</tr>\n"
    done
}

cat <<EOF
<table>
    <caption>$page_title</caption>
    <thead>
        <tr>
            <th>Hard Coded</th>
            <th>Hard Coded</th>
            <th>Hard Coded</th>
            <th>Hard Coded</th>
            <th>Hard Coded</th>
            <th>Hard Coded</th>
        </tr>
    </thead>
    <tbody>
`tbody`
    </tbody>
</table>
EOF

Выход

<table>
    <caption>Page Title</caption>
    <thead>
        <tr>
            <th>Hard Coded</th>
            <th>Hard Coded</th>
            <th>Hard Coded</th>
            <th>Hard Coded</th>
            <th>Hard Coded</th>
            <th>Hard Coded</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>

Пояснение

Идея состоит в том, чтобы извлекать данные строка за строкой, повторяя до последней строки. Этот фрагмент даст вам количество строк:

grep '<div ' demo.html | wc -l

Затем, используя nth-of-type(n)в качестве селектора, вы можете захватить всю строку вместо столбца. Вам нужно передать его grep '\S', чтобы избавиться от пустых строк. Затем, перейдя к paste -s -d, -, вы получите результат, разделенный запятыми.

IFS=, row=$(cat demo.html | pup "body div.row:nth-of-type($i) text{}" | grep '\S' | paste -s -d, -)

printf '\t\t\t<td>%s</td>\n' $rowбудет расширен до printf '\t\t\t<td>%s</td>\n' 'Text 1' 'Text 2'..., и каждый из аргументов будет заключен в<td>...</td>

Вы можете полностью удалить часть \t, она просто напечатает результат с отступом.

1
18.03.2021, 23:14

Следующее должно более или менее сделать это, имейте в виду, что я:

  • Только написал, не проверял. Изменить :Теперь я протестировал его, исправил некоторые ошибки, и, похоже, он работает.
  • Игнорирование крайних случаев (несколько <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;
2
18.03.2021, 23:14

Теги

Похожие вопросы