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

Более эффективный способ поиска и дег миллионов файлов

У меня есть работа, выполняемая на моем сервере в командной строке в течение двух дней:

find data/ -name filepattern-*2009* -exec tar uf 2009.tar {} ;

Он принимает навсегда, а затем некоторые. Да, в целевом каталоге есть миллионы файлов. (Каждый файл является ничтожным 8 байтов в структуре хэшированного хэширования.) Но просто работает...

find data/ -name filepattern-*2009* -print > filesOfInterest.txt

... занимает всего два часа. По той ставке, что моя работа работает, она не будет закончена на пару недель. Это кажется необоснованным. Есть ли более эффективный способ сделать это? Возможно, с более сложным bash script?

Вторичные вопросы: "Почему мой текущий подход настолько медленный?"

4b9b3361

Ответ 1

Если вы уже сделали вторую команду, которая создала список файлов, просто используйте параметр -T, чтобы сообщить tar прочитать имена файлов из этого списка сохраненных файлов. Запуск 1 tar-команды vs N tar-команд будет намного лучше.

Ответ 2

Один из вариантов заключается в использовании cpio для создания архива tar-формата:

$ find data/ -name "filepattern-*2009*" | cpio -ov --format=ustar > 2009.tar

cpio работает со списком имен файлов из stdin, а не с каталогом верхнего уровня, что делает его идеальным инструментом для этой ситуации.

Ответ 3

Здесь комбинация find-tar, которая может делать то, что вы хотите, без использования xargs или exec (что должно привести к заметному ускорению):

tar --version    # tar (GNU tar) 1.14 

# FreeBSD find (on Mac OS X)
find -x data -name "filepattern-*2009*" -print0 | tar --null --no-recursion -uf 2009.tar --files-from -

# for GNU find use -xdev instead of -x
gfind data -xdev -name "filepattern-*2009*" -print0 | tar --null --no-recursion -uf 2009.tar --files-from -

# added: set permissions via tar
find -x data -name "filepattern-*2009*" -print0 | \
    tar --null --no-recursion --owner=... --group=... --mode=... -uf 2009.tar --files-from -

Ответ 4

Для этого есть xargs:

find data/ -name filepattern-*2009* -print0 | xargs -0 tar uf 2009.tar

Угадайте, почему это медленно, так как информации не так много. Какова структура каталога, какая файловая система вы используете, как она была настроена при создании. Имея миллионы файлов в одном каталоге, довольно сложная ситуация для большинства файловых систем.

Ответ 5

Чтобы правильно обрабатывать имена файлов со странными (но законными) символами (такими как новые строки,...), вы должны записать свой список файлов в файлыOfInterest.txt, используя find -print0:

find -x data -name "filepattern-*2009*" -print0 > filesOfInterest.txt
tar --null --no-recursion -uf 2009.tar --files-from filesOfInterest.txt 

Ответ 6

Как у вас в настоящее время есть вещи, вы вызываете команду tar каждый раз, когда находит файл, что не удивительно медленно. Вместо того, чтобы печатать два часа, а также время, необходимое для открытия архива tar, проверьте, устарели ли файлы и добавили их в архив, вы фактически умножаете эти моменты вместе. У вас может быть более успешный вызов команды tar сразу после того, как вы собрали все имена, возможно, используя xargs для выполнения вызова. Кстати, надеюсь, вы используете 'filepattern- * 2009 *', а не filepattern- * 2009 *, поскольку звезды будут расширены оболочкой без кавычек.

Ответ 7

Простейший (также удалите файл после создания архива):

find *.1  -exec tar czf '{}.tgz' '{}' --remove-files \;