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

Янв 13th, 2022 | Posted by | Filed under Linux, PC, Software

Возникла тут нужда статистической выборки по определённому неструктурированному хранилищу. Задача, как оказалось, довольно тривиальная, хотя, на первый взгляд, так не показалось. Сотрудники несколько лет сканировали документы и складывали их, предположим, в Папка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 и т.д. замечательно загрузились и всё легко подсчиталось.

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

No comments yet.