copy recursively skipping directories with specific name

6,627

Solution 1

You want rsync:

rsync -va --exclude=foo --exclude=bar ~/directory_to_copy /path/to/copy 

--exclude is used to exclude unwanted files or directories.

-v makes rsync verbose (optional).

-a tells rsync to copy recursively and preserve file attributes. This is optional but, if you don't use -a, you likely want to use -r to copy recursively.

For more complex requirements, both exclude and include options can be specified. It is even possible to change the exclude/include settings from one directory to another by specifying the -F option and placing .rsync-filter files in various locations in the source directory hierarchy. man rsync has details.

Solution 2

you can use find for that

find -depth ! -wholename '*foo*' ! -wholename '*bar*' -exec cp --parents '{}' /target/dir/ \;

note that you will a) need -depth to make sure you first find the directories that need to be omitted and b) use the --parents option to cp to create the full path while copying.

This will however also skip empty folders as -r in cp cannot be used as then ALL filed would be copied once find comes to ./firstDIR .

Share:
6,627

Related videos on Youtube

Loom
Author by

Loom

Updated on September 18, 2022

Comments

  • Loom
    Loom almost 2 years

    I have a directory with ~100 Gb. I need to copy this directory to other place skipping specific folders (there is a lot of them). The following is a wrong code to demonstrate my needs.

    $ cp -r ~/directory_to_copy /path/to/copy --skip=foo --skip=bar
    

    There is an example of result this command. Original directory tree is

    ~/directory_to_copy
      aaa
        foo
        doo
          bar
      bbb
        ccc
          ddd
            bar
          eee
    

    Copied tree is

    /path/to/copy/
      aaa
        doo
      bbb
        ccc
          ddd
          eee
    

    How to write command for my purposes?

  • Matthias Urlichs
    Matthias Urlichs almost 9 years
    Actually, -a has the same effect as a bunch of other flags, one of which is -r(--recursive) which is not optional here.
  • John1024
    John1024 almost 9 years
    @MatthiasUrlichs Good point. Answer updated with info on -r.
  • heemayl
    heemayl almost 9 years
    Why not just path, wholename is less portable too..
  • FelixJN
    FelixJN almost 9 years
    might as well work, the ! could also be avoided with -prune like in ... -path '*foo*' -o -path '*bar*' -prune -o -exec ...
  • Matthias Urlichs
    Matthias Urlichs almost 9 years
    you can upvote comments, you know ;-)