Как скопировать избранные файлы вместе со структурой каталогов

Бывают ситуации когда необходимо скопировать выборочные файлы вместе со всей структурой каталогов. В данной ситуации одним cp -a не обойтись - ибо он копирует все подряд. На помощь приходит комманда cpio! :) Простой пример:
find /source_path | cpio -pdmuv /dest_path
здесь:
  • find /source_path - формируем на вход список файлов для копирования. Можно выдать уже подготовленный список из какого-либо файла, можно выдать из большого конвеера с обработчиками имен и тд.
  • cpio -pdmuv /dest_path - копируем файлы, пришедшие в stdin в папочку /dest_path, здесь опции означают:
    • -p - читать список имен файлов из стандартного потока (stdin)
    • -d - при необходимости создавать каталоги
    • -m - время изменения файла делать как у источника
    • -u - если такие файлы уже существуют, то затереть их
    • -v - вывести в стандартный вывод (stdout) список копируемых файлов
cpio создает полные пути, как они ему и пришли на вход. Т.е. если вы на вход подаете /aaa/bbb/ccc, то в результате получите /dest_path/aaa/bbb/ccc. По-этому используйте относительные пути (начинаются с символа точки . ), а не абсолютные. К примеру, в ситуации когда вы разрабатываете свой дистрибутив (который, к примеру, лежит у вас по адресу /home/user/my_dist) и нужно скопировать часть файлов в другую папку с сохранением всей структуры каталогов (к примеру в /home/user/new_dist) - перейдите в папку /home/user/my_dist и выполняйте выше приведенную команду от туда, чтобы оперировали с относительными путями. В скриптах же, где чаще всего используются абсолютные пути, можно использовать под-оболочку:
(cd /source_path; find . | cpio -pdmuv /dest_path)
Здесь cd - изменяет текущей каталог, но так как это делается в подоболочке, то при выходе из нее текущий каталог остается прежним.