Подтвердить что ты не робот

Как лучше всего посчитать результаты поиска?

Мое текущее решение будет find <expr> -exec printf '.' \; | wc -c, но это занимает слишком много времени, когда результатов более 10000. Нет ли более быстрого/лучшего способа сделать это?

4b9b3361

Ответ 1

Попробуйте это вместо (требуется find -printf поддержка):

find <expr> -type f -printf '.' | wc -c

Он будет более надежным и быстрее, чем подсчет строк.

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


Немного скажите:

$ ls -1
a
e
l
ll.sh
r
t
y
z

Мой примерный отрывок:

$ time find -type f -printf '.' | wc -c
8

real    0m0.004s
user    0m0.000s
sys     0m0.007s

С полными строками:

$ time find -type f | wc -l
8

real    0m0.006s
user    0m0.003s
sys     0m0.000s

Итак, мое решение быстрее =) (важная часть - это строка real)

Ответ 2

Почему бы не

find <expr> | wc -l

как простое переносное решение? Ваше исходное решение порождает новый процесс printf для каждого найденного файла, и это очень дорого (как вы только что нашли).

Обратите внимание, что это будет превышать, если у вас есть имена файлов с встраиваемыми новыми строками, но если у вас есть это, то я подозреваю, что ваши проблемы немного глубже: -)

Ответ 3

Это решение, конечно, медленнее, чем некоторые другие решения find -> wc, но если вы были склонны делать что-то еще с именами файлов в дополнение к их подсчету, вы могли бы read из вывода find.

n=0
while read -r -d ''; do
    ((n++)) # count
    # maybe perform another act on file
done < <(find <expr> -print0)
echo $n

Это просто модификация решение, найденное в BashGuide, которое правильно обрабатывает файлы с нестандартными именами, создавая разделитель вывода find a NUL байта с использованием print0 и чтения из него с использованием '' (NUL byte) в качестве разделителя циклов.

Ответ 4

Это моя функция countfiles в моем ~/.bashrc (она достаточно быстро, должна работать для Linux и FreeBSD find) и не обманывается путями файлов, содержащими символы новой строки, а окончательный wc просто подсчитывает NUL байт):

countfiles () 
{ 
   command find "${1:-.}" -type f -name "${2:-*}" -print0 | 
       command tr -dc '\0' | command wc -c;
return 0
}

countfiles

countfiles ~ '*.txt'

Ответ 5

Мне нравится, когда я натыкаюсь на соревнование по скорости. Ничего плохого в использовании wc, но до тех пор, пока мы сравниваем - вот (я думаю) самое портативное и быстрое решение: ``

$ time (i=0; for d in /dev/sd*[a-z]; do ((i++)); done; echo $i)
25

real    0m0.001s
user    0m0.000s
sys     0m0.000s

По сравнению с использованием find/wc:

$ time find /dev/sd*[a-z] | wc -l
25

real    0m0.006s
user    0m0.000s
sys     0m0.004s

$ time find /dev/sd*[a-z] -printf . | wc -c
25

real    0m0.005s
user    0m0.000s
sys     0m0.000s

Обратите внимание, что если вам нужно учитывать скрытые файлы, вам нужно будет иметь 2 аргумента в вашем цикле for: for devfile in /dev/.* /dev/*; do ... И он по-прежнему работает быстрее.

Счастливый взлом!