Copy only folders not files?

38,382

Solution 1

If you want to mirror a directory skeleton and copy no files:

find -type d -links 2 -exec mkdir -p "/path/to/backup/{}" \;

What's going on here:

  • Find is only selecting directories
  • We're using -links 2 to find the deepest possible directories.
  • mkdir -p will make any missing directories along the way.

I've done it like this rather than find -type d -exec mkdir -p "/path/to/backup/{}" \; because it'll cut out on a whole buttload of mkdir calls. We can quickly prove this with a little test. Here's the test tree followed by what I ran to compare the two commands:

$ tree
.
├── dir1
│   ├── dir2
│   │   └── dir3
│   ├── dir7
│   └── dir8
└── dir9
    └── dir0

$ pr -m -t <(find -type d) <(find -type d -links 2)
.                               ./dir1/dir8
./dir1                          ./dir1/dir2/dir3
./dir1/dir8                     ./dir1/dir7
./dir1/dir2                     ./dir9/dir0
./dir1/dir2/dir3
./dir1/dir7
./dir9                  
./dir9/dir0 

And that's only going to get better in a real-word solution with thousands of directories.

Solution 2

Quite easily done with python one-liner:

bash-4.3$ tree
.
├── ABC
├── set_pathname_icon.py
├── subdir1
│   ├── file1.abc
│   └── file2.abc
├── subdir2
│   ├── file1.abc
│   └── file2.abc
└── subdir3
    └── subdir4
        └── file1.txt

4 directories, 7 files
bash-4.3$ python -c 'import os,sys;dirs=[ r for r,s,f in os.walk(".") if r != "."];[os.makedirs(os.path.join(sys.argv[1],i)) for i in dirs]' ~/new_destination
bash-4.3$ tree ~/new_destination
/home/xieerqi/new_destination
├── subdir1
├── subdir2
└── subdir3
    └── subdir4

As script this could be rewritten like so:

#!/usr/bin/env python
import os,sys
dirs=[ r for r,s,f in os.walk(".") if r != "."]
for i in dirs:
    os.makedirs(os.path.join(sys.argv[1],i)) 
Share:
38,382

Related videos on Youtube

Shannon
Author by

Shannon

Updated on September 18, 2022

Comments

  • Shannon
    Shannon almost 2 years

    Is there a way to copy an entire directory, but only the folders? I have a corrupt file somewhere in my directory which is causing my hard disks to fail.

    So instead of copying the corrupt file to another hard disk, I wanted to just copy the folders, because I have scripts that search for hundreds of folders, and I don't want to have to manually create them all.

    I did search the cp manual, but couldn't see anything (I may have missed it)

    Say I have this structure on my failed HDD:

    dir1
        files
        dir2
            files
            files
            dir4
    dir3
    files
    

    All I a want is the directory structure, not any files at all.

    So I'd end up with on the new HDD:

    dir1
        dir2
            dir4
    dir3
    

    Hoping someone knows some tricks!

  • Shannon
    Shannon over 10 years
    This is me being a noob, however how are you searching the old dir to copy to the backup? I can only see one path here
  • Oli
    Oli over 10 years
    If you don't specify a path, find uses the current working directory as the starting point. If you wish to use another path use the syntax: find /path/to/search/ -type.....
  • Shannon
    Shannon over 10 years
    So I set my directory to a certain folder that contains the skeleton I want to copy, run find -type d -exec mkdir -p "/media/jinglez/TVSeries/TV Series"/{}" \; and all should be okay? It seems to be taking a while :/
  • Shannon
    Shannon over 10 years
    I run this from normal terminal right?
  • Shannon
    Shannon over 10 years
    What does putting the path in quotes and the {} at the end of it mean? Also the \; I have never seen that in a terminal command before
  • Oli
    Oli over 10 years
    They're both specific to find's exec clause. {} means the current "found" filename and \; is just the escape to end the clause. By the looks of it, there's an extra " in your code up to no good, I'm sure... Should read: find -type d -links 2 -exec mkdir -p "/media/jinglez/TVSeries/TV Series/{}" \;
  • Trevor Boyd Smith
    Trevor Boyd Smith about 7 years
    Please note this solution may copy the directory structure but this solution does not retain the directories' permissions and attributes. Use rsync to copy the directory structure AND retain the permissions and attributes](stackoverflow.com/a/9242883/52074).