У меня есть каталог, содержащий сотни тысяч файлов.
Мне нужно перечислить выборку этих файлов (пример 10 файлов), не обрабатывая все файлы, найденные в каталоге, что займет слишком много времени обработки.
решение1
Я не думаю, что можно сделать выборку из всего списка файлов, не прочитав их все тем или иным способом, даже на уровне файловой системы.
Пока неих имена следуют шаблону, который есть (например, fileXXXXXXX), в этом случае вы могли бы предварительно сгенерировать случайный список имен перед доступом к файлам. Для такого большого количества файлов было бы странно, если бы их имена были случайными.
Но предположим, что вам не так повезло. Использование find
предпочтительнее, чем ls
, так как оно может экранировать вывод с помощью null, что делает его невосприимчивым к нестандартным символам в именах файлов. Если мы не хотим читать все файлы, быстрее всего использовать те, что находятся в начале списка. Чтобы получить лучшую выборку, я бы сначала использовал большую выборку ( $oversamplesize
ниже), а затем сделал бы случайную подвыборку размера $samplesize
оттуда. Мне не удалось сделать sort -R
или shuf
хорошо работать с разделителями null, поэтому перемешивание и окончательный выбор выполняются с помощью awk
:
find ~ -type f -print0 |
grep --null --null-data -m ${oversamplesize:-100} . |
awk -v samplesize=${oversamplesize:-11} -vRS='\0' -vORS='\0' \
'{ a[NR]=$0 } END {srand(); while (i<samplesize) { b=(int(rand()*10000)%samplesize); if (b in c) {continue;} else {c[b]=a[b]; print a[b]; i++;} }; }' |
xargs -0 echo # echo here being just a dummy
Два примечания здесь. По какой-то причине он часто также печатает пустое имя файла, поэтому я увеличил размер выборки на всякий случай. Тривиальное примечание — не забыть изменить путь поиска (~ здесь) и финальную команду.