find: Copying A Subset of Files

1 
1 10.2 Copying A Subset of Files
1 ==============================
1 
1 Suppose you want to copy some files from '/source-dir' to '/dest-dir',
1 but there are a small number of files in '/source-dir' you don't want to
1 copy.
1 
1    One option of course is 'cp /source-dir /dest-dir' followed by
1 deletion of the unwanted material under '/dest-dir'.  But often that can
1 be inconvenient, because for example we would have copied a large amount
1 of extraneous material, or because '/dest-dir' is too small.  Naturally
1 there are many other possible reasons why this strategy may be
1 unsuitable.
1 
1    So we need to have some way of identifying which files we want to
1 copy, and we need to have a way of copying that file list.  The second
1 part of this condition is met by 'cpio -p'.  Of course, we can identify
1 the files we wish to copy by using 'find'.  Here is a command that
1 solves our problem:
1 
1      cd /source-dir
1      find . -name '.snapshot' -prune -o \( \! -name '*~' -print0 \) |
1      cpio -pmd0   /dest-dir
1 
1    The first part of the 'find' command here identifies files or
1 directories named '.snapshot' and tells 'find' not to recurse into them
1 (since they do not need to be copied).  The combination '-name
1 '.snapshot' -prune' yields false for anything that didn't get pruned,
1 but it is exactly those files we want to copy.  Therefore we need to use
1 an OR ('-o') condition to introduce the rest of our expression.  The
1 remainder of the expression simply arranges for the name of any file not
1 ending in '~' to be printed.
1 
1    Using '-print0' ensures that white space characters in file names do
1 not pose a problem.  The 'cpio' command does the actual work of copying
1 files.  The program as a whole fails if the 'cpio' program returns
1 nonzero.  If the 'find' command returns non-zero on the other hand, the
1 Unix shell will not diagnose a problem (since 'find' is not the last
1 command in the pipeline).
1