Поиск файлов по иродовому примеру :)

Возникла тут нужда статистической выборки по определённому неструктурированному хранилищу. Задача, как оказалось, довольно тривиальная, хотя, на первый взгляд, так не показалось. Сотрудники несколько лет сканировали документы и складывали их, предположим, в Папка1, потом перестали их складывать туда и создали Папка2. За время этого сканирования сменилось 4 начальника, у которых менялось видение того, как это всё должно храниться, и когда-то файлы складывались, например, в Папка1\2007\декабрь\Иванов\характерный_параметр\номер дела\номер тома\документы.pdf, когда-то в Папка1\Петров\характерный_параметр\документы.pdf, иногда Папка2\Для экспорта\Название региона откуда документы\характерный_параметр\документы.pdf и т.д. и т.п. Всё общее, что это объединяет это — тип файлов, по которым делается выборка — *.pdf и выборка только по «характерный_параметр», которого несколько десятков вариантов в промежутке от 00 до 99 🙂

Понимая, что этот зоопарк сложно как-то классифицировать и даже простое рысканье по сотням тысяч вложенных папок с целью составления списка займёт недели, я как-то вдруг подумал, а не создать ли список вообще всех *.pdf в Папка1/2 с фильтрацией по всем вариантам «характерный_параметр».

Статистика требовала всего два параметра — количество файлов в хранилище и их суммарный объём. Хранилище на каком-то Win сервере (не очень было интересно выяснять, на каком, но осталось у меня подозрение, что это был Win2008srv). К сожалению, не было возможности долго поизучать возможности программ поиска под Win на предмет чего-либо интеллектуального и требующегося, поэтому принял решение примонтировать диск файлового хранилища к Linux системе и делать всё с помощью find и др.

Для подключения файлового хранилища создал файл /etc/creds, в котором написал:

username=логин
password=пароль

Подключение командой:

mount.cifs //serverip/diskshare /mnt -o credentials=/etc/creds,iocharset=utf8,file_mode=0777,dir_mode=0777,uid=nobody,gid=sambashare,vers=2.0

В конце пришлось дописать «vers=2.0» чтобы самба смогла подключиться с использующейся на сервере версией протокола smb.

Дальше переход в место монтирования и поиск по папкам с выводом в файл:

find Папка*/ -type f -name «*.pdf» -print0|xargs -t -0 -L1 ls -AlG>~/pdflist

Ищем файл (-type f) с именем по шаблону (-name «*.pdf») и выводим найденное в консоль (-print0), что вывелось обрабатывается пакетным обработчиком xargs, передавая построчно (-L1) команде ls, которая добавляет размер файла к каждому файлу списка и выгружает результаты в файл. Всего в моём случае получилось 2.6 Гб список. Но в нём так же присутствовали разные pdf, которые не должны были попасть в отчёт, поскольку в них не было «характерного параметра».

Из сформированного файла со списком всех *.pdf файлов можно сделать выборку по нужным параметрам «характерный_параметр» и у меня ещё были 00…99. Вот так:

for ((i=0;i<10;i++)) do cat pdflist|grep характерный_параметр0$i\ >pdflist-0$i;done

for ((i=10;i<100;i++)) do cat pdflist|grep характерный_параметр$i\ >pdflist-$i;done

Первая команда создаёт список с характерный_параметр00…характерный_параметр09, вторая — с характерный_параметр10…характерный_параметр99.

Всё замечательно! Теперь можно обратно собрать списки со всеми характерными параметрами:

cat pdflist-* >pdflist-all

Получился список размером порядка 2 Гб в несколько млн строк. Такой список не загрузить в электронную таблицу и не просуммировать размеры файлов по столбцам. Я попробовал загрузить в LibreOffice Calc, но у него нет возможности загрузить более 65536 строк, поэтому воспользовался Excel. Для него я разбил список на фрагменты по 1 млн строк:

split -l 1000000 ./pdflist-all

Полученные файлы xaa, xab, xac и т.д. замечательно загрузились и всё легко подсчиталось.

Почему пример иродов? Очень просто! Это же Ирод решил убить всех младенцев без разбора, чтобы не пропустить никого 🙂

Запись опубликована в рубрике Linux, PC, Software с метками , , , , , , , , , , , , , , , . Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *