I want to copy my directory structure excluding the files. Is there any option in the tar to ignore all files and copy only the Directories recursively.
5 Answers
You can use find to get the directories and then tar them:
find .. -type d -print0 | xargs -0 tar cf dirstructure.tar --no-recursion
If you have more than about 10000 directories use the following to work around xargs limits:
find . -type d -print0 | tar cf dirstructure.tar --no-recursion --null --files-from -
-
1In earlier GNU tars apparently the position where you placed the **--no-recursion** argument did not matter for it to work while in more current versions it apparently needs to preceed the **--files-from** option... My backups just exploded after upgrading from Debian Wheezy to Debian Stretch which includes GNU tar 1.29. I edited the answer accordingly. – Gunter Ohrner May 30 '18 at 13:23
-
I've edited the answer and moved `--no-recursion` before `--files-from`. – Tometzky Jul 02 '19 at 08:55
Directory names that contain spaces or other special characters may require extra attention. For example:
$ mkdir -p "backup/My Documents/stuff"
$ find backup/ -type d | xargs tar cf directory-structure.tar --no-recursion
tar: backup/My: Cannot stat: No such file or directory
tar: Documents: Cannot stat: No such file or directory
tar: backup/My: Cannot stat: No such file or directory
tar: Documents/stuff: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
Here are some variations to handle these cases of "unusual" directory names:
$ find backup/ -type d -print0 | xargs -0 tar cf directory-structure.tar --no-recursion
Using -print0 with find will emit filenames as null-terminated strings; with -0 xargs will interpret arguments that same way. Using null as a terminator helps ensure that even filenames with spaces and newlines will be interpreted correctly.
It's also possible to pipe results straight from find
to tar
:
$ find backup/ -type d | tar cf directory-structure.tar -T - --no-recursion
Invoking tar with -T - (or --files-from -) will cause it to read filenames from stdin, expecting each filename to be separated by a line break.
For maximum effect this can be combined with options for null-terminated strings:
$ find . -type d -print0 | tar cf directory-structure.tar --null --files-from - --no-recursion
Of these I consider this last version to be the most robust, because it supports both unusual filenames and (unlike xargs) is not inherently limited by system command-line sizes. (see xargs --show-limits
)

- 1,128
- 11
- 10
for i in `find . -type d`; do mkdir -p /tmp/tar_root/`echo $i|sed 's/\.\///'`; done
pushd /tmp/tar_root
tar cf tarfile.tar *
popd
# rm -fr /tmp/tar_root

- 8,531
- 3
- 21
- 35
go into the folder you want to start at (that's why we use find dot) save tar file somewhere else. I think I got an error leaving it right there. tar with r not c. I think with cf you keep creating new files and you only get the last set of file subdirectories. tar r appends to the tar file. --no-recursion because the find is giving you your whole list of files already so you don't want to recurse.
find . -type d |xargs tar rf /somewhereelse/whatever-dirsonly.tar --no-recursion
tar tvf /somewhereelse/whatever-dirsonly.tar |more to check what you got.

- 411
- 2
- 6