У меня есть задание, работающее на моем сервере при приглашении командной строки для двух дни теперь:
find data/ -name filepattern-*2009* -exec tar uf 2009.tar {} ;
Это берет навсегда, и затем некоторые. Да, в целевом каталоге существуют миллионы файлов. (Каждый файл составляет ничтожные 8 байтов в хорошо хешированной структуре каталогов.), Но просто выполнение...
find data/ -name filepattern-*2009* -print > filesOfInterest.txt
... занимает только два часа или около этого. На уровне работает мое задание, это не будет закончено в течение нескольких недель.. Это кажется неблагоразумным. Существует ли более эффективное, чтобы сделать это? Возможно, с более сложным сценарием удара?
Вопросы вторичного устройства, "почему мой текущий подход является настолько медленным?"
Если вы уже выполнили вторую команду, которая создала список файлов, просто используйте параметр -T
, чтобы tar прочитал файлы имена из этого сохраненного списка файлов. Намного лучше будет запустить 1 команду tar против N команд tar.
Для этого есть xargs:
find data/ -name filepattern-*2009* -print0 | xargs -0 tar uf 2009.tar
Догадаться, почему это так медленно, сложно из-за нехватки информации. Какова структура каталога, какую файловую систему вы используете, как она была настроена при создании. Наличие миллионов файлов в одном каталоге - довольно сложная ситуация для большинства файловых систем.
В настоящее время вы вызываете команду tar каждый раз, когда она находит файл, что неудивительно медленно. Вместо того, чтобы потратить два часа на печать плюс время, необходимое для открытия tar-архива, проверить, не устарели ли файлы, и добавить их в архив, вы фактически умножаете это время вместе. Возможно, вы добьетесь большего успеха, вызвав команду tar один раз, после того, как вы объедините все имена, возможно, используя xargs для выполнения вызова. Кстати, я надеюсь, что вы используете 'filepattern- * 2009 *', а не filepattern- * 2009 *, поскольку звездочки будут расширяться оболочкой без кавычек.
Один из вариантов - использовать cpio для создания архива в формате tar:
$ find data/ -name "filepattern-*2009*" | cpio -ov --format=ustar > 2009.tar
cpio изначально работает со списком имен файлов из stdin, а не каталог верхнего уровня, что делает его идеальным инструментом в этой ситуации.
Вот комбинация 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 -
Чтобы правильно обрабатывать имена файлов со странными (но допустимыми) символами (такими как новые строки, ...), вы должны записать свой список файлов в filesOfInterest.txt, используя найти -print0:
find -x data -name "filepattern-*2009*" -print0 > filesOfInterest.txt
tar --null --no-recursion -uf 2009.tar --files-from filesOfInterest.txt