Манипулирование текстом между двумя родителями - PullRequest
0 голосов
/ 03 февраля 2020

у меня есть следующий html текст, где число "tr" является динамическим c:

<tr>
    <td>Dec 1, 2019 11:12 PM</td>
    <td>some text1</td>
    <td>some text2</td>
    <td>some text3</td>
    <td>
        <input type=button value="Add" id="add" onCLick="add(12345)" data-toggle="modal" data-target="#add" />
    </td>
    <td></td>
</tr>

<tr>
    <td>Dec 5, 2019 4:33 PM</td>
    <td>some text1</td>
    <td>some text2</td>
    <td>some text3</td>
    <td>
        <input type=button value="Add" id="add" onCLick="add(12345)" data-toggle="modal" data-target="#add" />
    </td>
    <td></td>
</tr>

<tr>
    <td>Dec 9, 2019 1:06 PM</td>
    <td>some text1</td>
    <td>some text2</td>
    <td>some text3</td>
    <td>
        <input type=button value="Add" id="add" onCLick="add(12345)" data-toggle="modal" data-target="#add" />
    </td>
    <td></td>
</tr>

, и я хотел бы получить следующий результат:

Dec 1, 2019 11:12 PM | some text1 | some text2 | some text3 
Dec 5, 2019 4:33 PM | some text1 | some text2 | some text3 
Dec 9, 2019 1:06 PM | some text1 | some text2 | some text3 

i попытался использовать sed для группировки по:

sed '/^<tr>/d;:a;N;/^<\/tr>/M!s/\n/ /;ta;P;d'

, но, конечно, это не работает. Любое предложение, как с этим бороться?

Ответы [ 4 ]

0 голосов
/ 05 февраля 2020

Это может сработать для вас (GNU sed):

sed -E '/<tr>/{:a;x;/\n/{s/<\/?t[rd]>/\n/g;s/^\s.*//mg;s/\n+/ | /g;s/^...|...$//g;p};x;h;d};//!H;$!d;ba' file

Соберите строки между <tr> и <\tr> в поле удержания. Если в области удержания уже есть строки при обнаружении тега <tr>, манипулируйте коллекцией в требуемом формате: замените теги символами новой строки, удалите строки, начинающиеся с пробела, замените одну или несколько строк новой строки | и top и tail первые 3 символа артефактов и распечатка изготовленной записи.

0 голосов
/ 03 февраля 2020

Это совершенно другой подход - просто чтобы дать вам представление о XSLT. Честно говоря, я обычно не фанат XSLT, и, честно говоря, это плохо для приведенного вами HTML примера. На самом деле, это плохое совпадение для этой проблемы, но было бы неплохо добавить его в обсуждение.

Во-первых, HTML не является строго XML совместимым. Но в этом случае было бы интересно отметить, что я должен был сделать с вашим вводом, чтобы сделать его XML совместимым:

  1. Цитировать 'кнопку'. Теперь атрибут type для входных элементов заключен в кавычки:

  2. Мне пришлось обернуть все элементы в элемент root. Я выбрал

Вот подход XSLT:

function xsl {
cat  <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:mpd="urn:mpeg:dash:schema:mpd:2011" version="1.0">
  <xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
  <xsl:param name="locale">en</xsl:param>
  <xsl:template match="//tr"><xsl:value-of select="td[1]"/> | <xsl:value-of select="td[2]"/> | <xsl:value-of select="td[3]"/> | <xsl:value-of select="td[4]"/></xsl:template>
</xsl:stylesheet>
EOF
}

xsltproc <( xsl ) -  <<EOF
<table>
<tr>
    <td>Dec 1, 2019 11:12 PM</td>
    <td>some text1</td>
    <td>some text2</td>
    <td>some text3</td>
    <td>
        <input type="button" value="Add" id="add" onCLick="add(12345)" data-toggle="modal" data-target="#add" />
    </td>
    <td></td>
</tr>

<tr>
    <td>Dec 5, 2019 4:33 PM</td>
    <td>some text1</td>
    <td>some text2</td>
    <td>some text3</td>
    <td>
        <input type="button" value="Add" id="add" onCLick="add(12345)" data-toggle="modal" data-target="#add" />
    </td>
    <td></td>
</tr>

<tr>
    <td>Dec 9, 2019 1:06 PM</td>
    <td>some text1</td>
    <td>some text2</td>
    <td>some text3</td>
    <td>
        <input type="button" value="Add" id="add" onCLick="add(12345)" data-toggle="modal" data-target="#add" />
    </td>
    <td></td>
</tr>
</table>
EOF

А вот вывод на MA C:

Dec 1, 2019 11:12 PM | some text1 | some text2 | some text3

Dec 5, 2019 4:33 PM | some text1 | some text2 | some text3

Dec 9, 2019 1:06 PM | some text1 | some text2 | some text3
0 голосов
/ 04 февраля 2020

Как уже было сказано, используйте синтаксический анализатор HTML, например xidel.

Xidel - инструмент командной строки для загрузки и извлечения данных из HTML / XML страниц, а также JSON -API, используя CSS, XPath 3.0, XQuery 3.0, JSONiq или шаблоны шаблонов. Он также может создавать новые или преобразованные документы XML / HTML / JSON.

xidel -s input.html -e '//tr/join(td[position()<5]," | ")'
Dec 1, 2019 11:12 PM | some text1 | some text2 | some text3
Dec 5, 2019 4:33 PM | some text1 | some text2 | some text3
Dec 9, 2019 1:06 PM | some text1 | some text2 | some text3

В человеческом смысле: для каждого tr -узла выберите текстовый узел первого 4 td -узлы и соедините их вместе, разделив их |.

См. также это демо xidelcgi .

0 голосов
/ 03 февраля 2020

Если вам не нужно быстрое и грязное решение, синтаксический анализ html должен выполняться с использованием синтаксического анализатора html, как сказано в комментариях.

Например, с использованием python:

import bs4 # bs4 stands for beautifulsoup, a html parser
import csv

# I open both input and output file
with open(<input>) as myinput, open(<output>, "w") as myoutput:
    # I parse the html
    soup = bs4.BeautifulSoup(myinput, 'html.parser')
    # I set the delimiter for the csv
    csvwriter = csv.writer(myoutput, delimiter="|")

    # For each tr tag
    for tr in soup.find_all('tr'):
        # Here I create a list that contains all text from td
        rows = [td.text for td in tr.find_all('td')]
        # I write the 4th first values as a csv row
        csvwriter.writerow(rows[:4])

Теперь, если вы не уверены в этом хорошем решении, давайте посмотрим на быстрое и грязное, используя awk:

awk '
   # I define here input and output delimiters
   BEGIN{FS="<|>"; OFS=" | "}
   # I store info in array td_info
   /<td>/{td_info[++counter]=$3} 
   # I print the info I need and clean td_info array and counter
   /<\/tr>/{
       print td_info[1], td_info[2], td_info[3], td_info[4]
       counter=0
       delete td_info
   }
' <input.html>

Вывод:

Dec 1, 2019 11:12 PM | some text1 | some text2 | some text3
Dec 5, 2019 4:33 PM | some text1 | some text2 | some text3
Dec 9, 2019 1:06 PM | some text1 | some text2 | some text3
...