no-style

Как парсить, качать и обрабатывать гигабайты текста на Linux

sed обработать много текста
Как то раз я столкнулся с довольно нестандартной задачей. Мне понадобилось скачать, а затем обработать большой текстовый фаил. Задача заключалась в том чтобы полученный в последствии текст нужно было очистить от знаков препинания и мусора, а так же полностью удалить английский текст, оставив только русский. Далее необходимо было получить только уникальные слова из полученного текста. Я решил описать весь проделанный процесс от начала и до конца.


Парсинг текста

Так как у кого то могут возникнуть затруднения с поиском большого количества текста, предлагаю сразу все рассмотреть на конкретном примере.

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

mkdir -p ~/Scripts/Books && nano ~/Scripts/bookdwnload.sh

И наполняем его таким содержимым


Делаем наш скрипт executable

chmod +x ~/Scripts/bookdwnload.sh

И запускаем его (осторожно траффик)

cd ~/Scripts/Books && ./bookdwnload.sh &

Начнется парсинг url на прямые ссылки до txt фаилов, а затем их скачивание. Процесс довольно долгий, поэтому если вам не хочется скачивать весь раздел, то измените параметр for page in {1..1015}. В данный момент он берет все страницы от 1 до 1015 той!

После скачивания у нас будет очень много фаилов ~25 тысяч. Прочтем все их содержимое в 1 фаил, чтобы было удобнее, а остальные фаилы удалим. На момент написания статьи весь скачанный раздел занимал 5 gb текста.

cd ~/Scripts/Books && cat *.txt >> ~/Scripts/bigfile.txt && rm -rf ~/Scripts/Books






Кодировка текста

Полученный на первом этапе фаил необходимо перевести в правильную кодировку, перед работой с ним. Посмотрим его кодировку с помощью enca (если у вас нет этой программы то установить ее не составит труда на любом дистрибутиве) Забегая вперед сразу скажу что полученный фаил имеет кодировку windows-1251

enca bigfile.txt


Так как мы хотим избавиться от ненужных символов, нам придется сначала перевести фаил в нужную кодировку с помощью iconv, но тут сразу сталкиваемся с проблемой.

Дело в том, что для этого в процессе обработки фаила - iconv будет полностью загружать весь фаил в оперативную память, а ее ведь может и не хватить, поэтому cначала придется разбить большой фаил на части, каждую из которых мы переведем в UTF-8, а затем снова прочтем результат в 1 большой фаил.

split -a 1 -d -b 700M bigfile.txt kusok.txt.part && rm -rf bigfile.txt

Таким образом мы получили несколько фаилов по 700 mb и удалили большой фаил. Теперь поочередно изменим кодировку в каждом фаиле на UTF-8 а так же удалим иcходный фаил (чтобы не мешал)

iconv -c -f WINDOWS-1251 -t UTF-8 kusok.txt.part0 >> part0.txt && rm -rf kusok.txt.part0

iconv -c -f WINDOWS-1251 -t UTF-8 kusok.txt.part1 >> part1.txt && rm -rf kusok.txt.part1

iconv -c -f WINDOWS-1251 -t UTF-8 kusok.txt.part2 >> part2.txt && rm -rf kusok.txt.part2

и так далее пока не преобразуем все фаилы. Обратите внимание что размер наших фаилов стал больше, когда мы перевели его в UTF-8.

Иногда бывает сразу несколько разных кодировок в 1 фаиле и iconv выдает ошибку связанную с тем, что не может распознать символ, именно поэтому мы используем iconv с ключем -c что означает что такие символы будут пропущены.

Теперь, прочтем содержимое всех фаилов в 1 фаил и удалим ненужные

cat *.txt >> utf-bigfile.txt && rm -rf part*.txt

Ну вот мы и подошли к самой интересной части.







Обработка текста

Теперь можем приступать к обработке большого фаила.

Несмотря на то, что мы скачали раздел русской литературы, там все равно присутствуют английские книги, а так же английский текст, поэтому уберем все символы кроме русских, а так же оставим пробелы между словами:

sed -i -e 's/[^а-яА-Я\ ]\+//g;s/\ \{2,\}/\ /g' utf-bigfile.txt

Убираем пробелы в начале строки

sed -i 's/^ *//g' utf-bigfile.txt

Убираем все пустые строчки

sed -i '/./!d' utf-bigfile.txt

Таким образом мы получили фаил состоящий только из русских слов, разделенный пробелами.


Заменяем пробел(ы) на перенос строки

sed -i -e 's/ /\n/g' utf-bigfile.txt

Приводим все слова к нижнему регистру

sed -i 's/[[:upper:]]/\l&/g' otjim.txt

Сортируем все по уникальности, оставляя по 1 уникальному слову среди всех остальных

cat otjim.txt | sort -u >> base.txt

Таким образом мы получили только уникальные слова, содержащиеся в 25 тысячах книг. Полученный из книг фаил изначально занимал 5 gb, после перевода его в UTF-8 увеличился почти в 2 раза, а после всех проделанных действий превратился в фаил с уникальными словами, занимающий 66 mb. Надеюсь было интересно, кстати все это лучше проделать с базой данных данных. Изначальная задача по получению уникальных словосочетаний из уникальных слов была решена - конец.

Комментарии