LINUX.ORG.RU

Использование grep, awk и sed для работы со «сплошным» текстом.

 , ,


0

1

Здравствуйте! Не могу самостоятельно решить следующую проблему, не хватает знаний: Есть .html файлы, где текст «идет» сплошняком, без строк, но из него нужно «вырезать» отдельные фрагменты, соответствующие шаблонам...

Например кусок такого текста:

  </td><td>妈,我可以看电视吗?</td></tr><tr><td></td><td> mā, wǒ kěyǐ kàn diànshì ma?</td></tr><tr><td></td><td><span style=«font-style:italic;»>Mum, can I watch TV?</span></td></tr><tr><td>

1-ый шаблон: '  </td><td>что-то там</td>' 2-ой шаблон: '<td></td><td> что-то там</td>' 3-ий шаблон: '<td><span style=«font-style:italic;»>что-то там</span>

Моя задача «вырезать» текст (妈,我可以看电视吗?; mā, wǒ kěyǐ kàn diànshì ma? ; Mum, can I watch TV?) после и до шаблона и вывести результат в новый файл.

Пожалуйста, помогите!!!


Классический еженедельный тред написания парсеров на malbolge и прочих регэкспах

anonymous
()
Ответ на: комментарий от Balantay

Люди бывают разными, разных специальностей. Я например врач и мне не нужно знать, что такая задача профессионально решается как-то по-другому. Поэтому я обратился к Вам на форум, к профессионалам. Это все равно что Вы бы зашли на медицинский форум и написали - «Пожалуйста, подскажите можно ли принимать антибиотики при вирусной инфекции?», а я бы Вам ответил - «Люди все еще пытаются лечить вирусные заболевания антибиотиками...», но совета бы так и не дал... пускай помирает...!

jarod
() автор топика
Ответ на: комментарий от jarod

Проблема в постановке вопроса. Если я зайду на форум врачей, то я создам тему «Чем лечить вирусную инфекцию», а не «Как лечить вирусную инфекцию тетрациклином», а тут формулировка именно такая.

Balantay
()
Ответ на: комментарий от Balantay

Хорошо, я понял. Тогда я рискну переформулировать вопрос. Как мне решить возникшую проблему, с помощью чего. Проблема в том, что таких файлов очень много и совет, который мне только что дали (перевести все в csv), к сожалению, не подходит. Тогда теряется изначальный смысл скрипта - помощь в рутинных задачах. Я не ленивый и не жду готового решения, мне достаточно совета, намека. Я с удовольствием покопаюсь на форумах и поищу ответ, если опытный человек подскажет, в каком направлении двигаться.

jarod
() автор топика
Ответ на: комментарий от anonymous

Спасибо Вам большое за совет, но в данном случае, к сожалению, это не выход из ситуации, так как таких файлов несколько тысяч. Проще просто с сайта копировать да и все. Но все равно спасибо за готовность помочь.

jarod
() автор топика
Ответ на: комментарий от jarod

Не для awk/grep/sed эти данные. Ставь тэги python, BeautifulSoup(если такой есть), lxml. Таблицу распарсить достаточно просто, вот пример. Но это всегда очень индивидуально. Лучше предоставить шаблонный кусок или целую страницу, в которой таблица такая, как везде и на её основе сделать. Так же что конкретно доставать, куда и как сохранять.

conformist ★★★
()
Ответ на: комментарий от jarod

Проще просто с сайта копировать

Что за сайт?

anonymous
()
Ответ на: комментарий от jarod

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

zolden ★★★★★
()

Если нужно просто убрать html-теги, то, например, так:

sed 's/<[^>]*>/ /g;s/<.*//;s/[^>]*>//' < file.html

Здесь используются 3 регулярки для sed:

1.

s/<[^>]*>/ /g;
удаляет все символы между < и >, включая их самих и заменяет всё это на 1 пробел (пробел нужен, чтобы текст, расположенный внутри разных тегов, не слипался, если он не отделён от тегов пробелом). Флаг g обозначает, что делаем это многократно в каждой строке.

2.

s/<.*//;
на тот случай, если некоторые теги занимают 2 строки, удаляем всё, начиная от открывающего тега (все теги, имевшие закрывающий тег в той же строке, уже удалены, поэтому ничего лишнего удалено не будет). Заменяем на пустую подстроку (здесь нечему слипаться, поэтому пробел не нужен). Флаг g тоже не нужен, т. к. удаляем до конца строки, т. е. 1 раз.

3.

s/[^>]*>//
то же самое, но для окончания тега, начатого на другой строке.

Недостаток этого скрипта в том, что он корректно удаляет однострочные и двухстрочные html-теги, но вот трёх- и более строчные не удалит. Точнее удалит только первую и последнюю строку. Кроме того, он не удаляет комментарии и ява- и пхп- скрипты.

Но общий шаблон для самого простого случая я, надеюсь, дал.

aureliano15 ★★
()
grep -Po "<td>.+?</td>" example.txt | sed "s/<[^>]*>//g"

-P перловый синтаксис регулярных выражений для использования нежадного квантификатора +?

-o выводит только совпавшие части строки

Результат

妈,我可以看电视吗?
 mā, wǒ kěyǐ kàn diànshì ma?
Mum, can I watch TV?

gorky ★★
()

lynx -dump, а потом уже grep, awk и sed

ananas ★★★★★
()

Распарсить html, как и любой xml, при условии его корректности, на баше даже без sed,grep и awk проще простого:

#!/bin/bash

rdom () { local IFS=\> ; read -d \< T V ; }

while rdom; do
    case $T in
        /* | \?* )
            ;;
        *)
            V=`echo "$V" | xargs`
            [ "$V" != "" ] && {
                echo $T \"$V\"
            }
            ;;
    esac
done

Этот скрипт, если скормить ему html

./htmlparse.sh < example.html
сделает из запощенного образца вот такое:

td «妈,我可以看电视吗?»
td «mā, wǒ kěyǐ kàn diànshì ma?»
span style=«font-style:italic;» «Mum, can I watch TV?»

Это если нужны только теги в которые заключено некое содержимое. Если заменить

echo $T \"$V\"
на
echo $V
то выведет только содержимое тегов, что, как понимаю, и требуется.
妈,我可以看电视吗?
mā, wǒ kěyǐ kàn diànshì ma?
Mum, can I watch TV?

Stanson ★★★★★
()
Последнее исправление: Stanson (всего исправлений: 2)

То есть нужно получить текст ТОЛЬКО между этими тегами? Если же нет и нужен весь текст то :D я немножко без грепов сделал))

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int stat = 0,
    out  = 0,
    in   = 1;

int main(int argc, char *argv[])
{
    for (int buff; (buff=getc(stdin)) != EOF;)
    {   
        if (buff == '<')
        {   
            while(buff=getc(stdin)!='>');
            stat = out;
            continue;
        };
           if (stat == out)
           {
                putc('\n',stdout);
                stat=in;
           };
           putc(buff,stdout);
    };
    return 0;
}
Вроде работает
gcc grep.c;
dron@gnu:~$ echo "</td><td>妈,我可以看电视吗?</td></tr><tr><td></td><td> mā, wǒ kěyǐ kàn diànshì ma?</td></tr><tr><td></td><td><span style=«font-style:italic;»>Mum, can I watch TV?</span></td></tr><tr><td>" |./a.out 

妈,我可以看电视吗?
mā, wǒ kěyǐ kàn diànshì ma?
Mum, can I watch TV?

можно так
./a.out < file.html #вывод в терминал
./a.out < file.html > out.txt #вывод в файл
А если их куча то
cat ./*.html | ./a.out > out.txt

Dron ★★★★★
()
Последнее исправление: Dron (всего исправлений: 1)
Ответ на: комментарий от Dron

Это будет работать быстрее чего угодно выше подсказанного, а если текст нужен выборочный, точно по тем шаблонам что ты указал, могу подправить. Так как фильтровать можно будет просто по сравнению строк, вывода только того что внутри именно этих шаблонов игнорируя всё остальное, но я не уверен что вместо font-style:italic будет font-style:normal по длинне подходит, а по смыслу уже нет или ещё тонна вариантов у меня на счёт стабильности твоих шаблонов в html, но если я не прав то можно)

Dron ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.