Next: , Previous: Deleting Files, Up: Worked Examples

10.2 Copying A Subset of Files

Suppose you want to copy some files from /source-dir to /dest-dir, but there are a small number of files in /source-dir you don't want to copy.

One option of course is cp /source-dir /dest-dir followed by deletion of the unwanted material under /dest-dir. But often that can be inconvenient, because for example we would have copied a large amount of extraneous material, or because /dest-dir is too small. Naturally there are many other possible reasons why this strategy may be unsuitable.

So we need to have some way of identifying which files we want to copy, and we need to have a way of copying that file list. The second part of this condition is met by cpio -p. Of course, we can identify the files we wish to copy by using find. Here is a command that solves our problem:

     cd /source-dir
     find . -name '.snapshot' -prune -o \( \! -name '*~' -print0 \) |
     cpio -pmd0   /dest-dir

The first part of the find command here identifies files or directories named .snapshot and tells find not to recurse into them (since they do not need to be copied). The combination -name '.snapshot' -prune yields false for anything that didn't get pruned, but it is exactly those files we want to copy. Therefore we need to use an OR (‘-o’) condition to introduce the rest of our expression. The remainder of the expression simply arranges for the name of any file not ending in ‘~’ to be printed.

Using -print0 ensures that white space characters in file names do not pose a problem. The cpio command does the actual work of copying files. The program as a whole fails if the cpio program returns nonzero. If the find command returns non-zero on the other hand, the Unix shell will not diagnose a problem (since find is not the last command in the pipeline).