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).