2012-04-11 2 views
3

У меня есть простая команда find, которая должна пройти миллионы файлов на сервере и найти некоторые с заданным суффиксом. Файлы записываются и удаляются с течением времени очень часто. Мне просто интересно, есть ли способ сделать поиск быстрее. Использование локации не может быть и речи, потому что создание базы данных для местоположения будет очень дорогостоящим.quick shell find

find /myDirWithThausandsofDirectories/ -name *.suffix 

На некоторых серверах эти команды занимают целые дни!

Любые мысли?

Спасибо,

+0

Это все, что вы можете сделать. find будет перебирать каталоги для вас, но переход через «большие» каталоги в системе unix, естественно, замедляется из-за того, как хранятся записи в каталоге. –

+0

сломать проблему? 'find /myDirWith../dira* -name * .suf & find /myDirWith../dirb* -name * .suf .... &' Также смотрите 'gnu-parallel' или' xargs -n' Good удачи! – shellter

+1

Возможно, это хороший случай для того, чтобы иметь что-то отличное от миллионов файлов, например. База данных GDBM или «реляционные» базы данных, такие как MySQL или PostGresQL, или noSQL, такие как mangodb. –

ответ

2

Вы можете использовать подсистему аудита для контроля за создание и удаление файлов. Объединение этого с начальным запуском find должно позволить вам создать базу данных файлов, которую вы можете обновить в реальном времени.

3

Разделить и покорить? предполагая, что MP os и процессор порождают несколько команд find для каждой вложенной папки.

for dir in /myDirWithThausandsofDirectories/* 
do find "$dir" -name "*.suffix" & 
done 

в зависимости от количества подкаталогов вы можете захотеть, чтобы контролировать количество процессов (find команд) работают в данный момент времени. Это будет немного сложнее, но выполнимо (т. Е. Используя оболочку bash, сохраните массив с pids из порожденных процессов $! и разрешите только новые, в зависимости от длины массива). Также вышесказанное не ищет файлы под корневым каталогом, просто быстрый пример этой идеи.

Если вы не знаете, как обрабатывать управление, время учиться;) This - действительно хороший текст на эту тему. This - это то, что вам нужно на самом деле. Но прочитайте все, чтобы понять, как это работает.

+0

вы также можете посмотреть на вещи, такие как 'nice' и' ionice', чтобы придать вашему сценарию больше приоритета, но я не уверен, что это будет иметь большое значение и, скорее всего, сделает машину непригодной для других вещей. – c00kiemon5ter

+0

Я не знаю, как контролировать количество процессов! – Amir

+1

Я отредактировал свой ответ, чтобы помочь :) – c00kiemon5ter

0

Поскольку вы используете простой глобус, вы можете использовать Рекурсивное подтачивание Bash. Пример:

shopt -s globstar 
for path in /etc/**/**.conf 
do 
    echo "$path" 
done 

Может быть быстрее, так как он использует внутренний потенциал оболочки с гораздо меньшей гибкостью, чем find.

Если вы не можете использовать Bash, но у вас есть предел глубины пути, вы можете явно перечислить различные глубины:

for path in /etc/*/*.conf /etc/*/*/*.conf /etc/*/*/*/*.conf 
do 
    echo "$path" 
done 
0

Вот код:

find /myDirWithThausandsofDirectories/ -d type maxdepth 1 > /tmp/input 
IFS=$'\n' read -r -d '' -a files < /tmp/input 


do_it() { 
    for f; do find $f -name *.suffix | sed -e s/\.suffix//g ; done 
} 

# Divide the list into 5 sub-lists. 
i=0 n=0 a=() b=() c=() d=() e=() 
while ((i < ${#files[*]})); do 
    a[n]=${files[i]} 
    b[n]=${files[i+1]} 
    c[n]=${files[i+2]} 
    d[n]=${files[i+3]} 
    e[n]=${files[i+4]} 
    ((i+=5, n++)) 
done 

# Process the sub-lists in parallel 
do_it "${a[@]}" >> /tmp/f.unsorted 2>/tmp/f.err & 
do_it "${b[@]}" >> /tmp/f.unsorted 2>/tmp/f.err & 
do_it "${c[@]}" >> /tmp/f.unsorted 2>/tmp/f.err & 
do_it "${d[@]}" >> /tmp/f.unsorted 2>/tmp/f.err & 
do_it "${e[@]}" >> /tmp/f.unsorted 2>/tmp/f.err & 
wait 
echo Find is Done! 

Единственная проблема, с которой я сталкиваюсь, - это некоторые из имен файлов (очень небольшой процент), частично. Я понятия не имею, какова была бы причина!

Смежные вопросы