Потребовалось обработать уже готовые отчеты в HTML файлах, а именно - из каждого файла-отчета взять конкретную ячейку таблицы и просуммировать, своего рода - SUM() и GROUP BY (в SQL). Сначала думал написать скрипт например на Python, который бы парсил HTML и т.д. и т.п., но... вспомнил что есть LibreOffice который умеет конвертировать файлы в headless режиме. Да, HTML файл не таблица XLS* и с ходу при попытке конвертации LibreOffice выдавал ошибку. Но он же прекрасно может работать с таблицами в HTML!? Открывает их в Calc или при вставке из буфера по Ctrl+V ... Вспомнил про "фишку" с Excel, что если переименовать файл в XLS, то Excel его без проблем открывает, попробовал тоже самое и о чудо - LibreOffice стал конвертировать переименованный HTML в XLS файл в CSV файл. Далее нужно из каждого файла взять из первой строки, во второй колонке число и просуммировать, ну это на Bash вообще легко...
В итого имеем скриптик фактически из трех строк (переименование, конвертирование, суммирование):
## копируем в отдельную папку обрабатываемые файлы
mkdir in out
cp -v *.html in
## добавляем в файлы кодировку, т.к. ее нет... в моей задаче это не принципиально.
sed -i -e "s/\(<\/title>\)/\1<meta charset='windows-1251'>/" in/*.html
## переименовываем файлы в XLS и заодно делаем имена покороче, просто цифровые.
rename 's/[^.]+KTSR([0-9]{2})[^.]+.html/in\/$1.xls/g' in/*.html
## конвертируем файлы в CSV
libreoffice --convert-to 'csv:Text - txt - csv (StarCalc):59,,0,3' in/*.xls --outdir out
## собственно суммируем то что нам надо (через head берем первую строку,
## cut разбиваем и берем 2 колонку, через past соединяем все в одну строку
## через символ + и передаем на bc (калькулятор)
head -qn 1 out/*.csv | cut -d";" -f2 | paste -sd+ | bc
rm -rf in out
Все! ... всего три строчки:
rename
libreoffice --convert-to ...
head -qn 1 out/*.csv | cut -d";" -f2 | paste -sd+ | bc
PS: Кстати, можно использовать этот метод для подготовки/загрузки данных в базу в том числе и из HTML таблиц. Об этом напишу как-нибудь позже.
PPS: Уверен что вообще одной строчкой можно решить, может сделаю позже.
Комментариев нет:
Отправить комментарий