<> == How can I recreate a directory hierarchy structure, without the files? == With the `cpio` program: {{{#!highlight bash cd -- "$srcdir" && find . -type d -print | cpio -dumpv -- "$dstdir" }}} or with the `pax` program: {{{#!highlight bash cd -- "$srcdir" && find . -type d -print | pax -rwdv -- "$dstdir" }}} or with GNU `tar`, and more verbose syntax: {{{#!highlight bash cd -- "$srcdir" && find . -type d -print | tar c --files-from - --no-recursion | tar x --directory "$dstdir" }}} This creates a list of directory names with `find`, non-recursively adds just the directories to an archive, and pipes it to a second `tar` instance to extract it at the target location. As you can see, `tar` is the least suited to this task, but people just adore it, so it has to be included here to appease the `tar` fanboy crowd. (Note: you can't even do this at all with a typical Unix `tar`. Also note: there is no such thing as "standard tar", as both `tar` and `cpio` were intentionally omitted from POSIX in favor of `pax`.) All the solutions above will fail if directory names contain newline characters. On many modern BSD/GNU systems, at least, they can be trivially modified to cope with that, by using `find -print0` and one of `pax -0` or `cpio -0` or `tar --null` (check your system documentation to see which of these commands you have, and which extensions are available). If you really don't have access to those options, you can probably, at least, use `! -path $'*\n*' -type d -print`, or better `-name $'*\n*' -prune -o -type d -print` (instead of `-type d -print`) to ignore directories that contain newline characters in their path, making sure `find` is run in the `C`/`POSIX` locale to also exclude file paths containing newline characters as well as sequence of bytes not forming valid characters in the user's locale. with find {{{#!highlight bash export dstdir mkdir -p -- "$dstdir" && cd -- "$srcdir" && find . -type d -exec sh -c \ 'cd -- "$dstdir" && mkdir -- "$@"' sh {} + }}} or with bash 4's `globstar` {{{#!highlight bash shopt -s globstar nullglob && cd -- "$srcdir" && dirs=(**/) && (( ${#dirs[@]} )) && cd -- "$dstdir" && mkdir -- "${dirs[@]}" }}} (though beware that will also copy symlinks to directories as directories; older versions of bash would also traverse symlinks when crawling the directory tree). or with zsh's recursive globbing and glob qualifiers: {{{#!highlight bash export srcdir dstdir zsh -ec ' cd -- "$srcdir" dirs=(**/*(/D)) cd -- "$dstdir" mkdir -- $dirs' }}} If you want to create stub files instead of full-sized files, the following is likely to be the simplest solution. The `find` command recreates the regular files using "dummy" files (empty files with the same timestamps): {{{#!highlight bash cd -- "$srcdir" && DSTDIR=$dstdir find . -type f -exec sh -c \ 'for i do touch -r "$i" -- "$DSTDIR/$i"; done' sh {} + }}} If your `find` can't handle `-exec +` then you can use `\;` instead of `+` at the end of the command. See [[UsingFind]] for explanations. ---- CategoryShell