## 9.17. Duplicating a Directory Tree

In many versions of find, the operator `{}`, used with the -exec operator, only works when it's separated from other arguments by whitespace. So, for example, the following command will not do what you thought it would:

>     % find . -type d -exec mkdir /usr/project/{} \;

You might have thought this command would make a duplicate set of (empty) directories, from the current directory and down, starting at the directory /usr/project. For instance, when the find command finds the directory ./adir, you would have it execute mkdir /usr/project/./adir (mkdir will ignore the dot; the result is /usr/project/adir).

That doesn't work because those versions of find don't recognize the `{}` in the pathname. The GNU version does expand `{}` in the middle of a string. On versions that don't, though, the trick is to pass the directory names to sed , which substitutes in the leading pathname:

>     % find . -type d -print | sed 's@^@/usr/project/@' | xargs mkdir
>     % find . -type d -print | sed 's@^@mkdir @' | (cd /usr/project; sh)

Let's start with the first example. Given a list of directory names, sed substitutes the desired path to that directory at the beginning of the line before passing the completed filenames to xargs and mkdir. An `@` is used as a sed delimiter because slashes (`/`) are needed in the actual text of the substitution. If you don't have xargs, try the second example. It uses sed to insert the mkdir command, then it changes to the target directory in a subshell where the mkdir commands will actually be executed.

-- JP

Copyright © 2003 O'Reilly & Associates. All rights reserved.