1

I have the following directory structure:

                            Main_Dir
                               |
              -----------------------------------
            Subdir1         Subdir2         Subdir3
               |               |               |
          -----------     -----------     -----------
          |    |    |     |    |    |     |    |    |            
         fo1  fo2  f03   fo1  fo2  f03   fo1  fo2  f03

I want to copy all the subdirectories (Subdir1, Subdir2, Subdir3) to a new folder. But how would I only copy fo1 and fo2 folders to the new place?

1
  • Please clarify your question: where do you want to copy the fo1 and fo2 folders?
    – jobin
    Nov 8, 2013 at 7:57

3 Answers 3

2

Use rsync:

rsync -av --exclude="f03" /path/to/Main_Dir/ /pth/to/destination
1

The best option is to use globs and cp with its --parents option. In your case:

cp -nvr --parents -- Main_Dir/*/fo{1,2} Destination/

Look:

gniourf@somewhere$ mkdir -pv Main_Dir/Subdir{1..3}/f{o{1,2},03}
mkdir: created directory `Main_Dir'
mkdir: created directory `Main_Dir/Subdir1'
mkdir: created directory `Main_Dir/Subdir1/fo1'
mkdir: created directory `Main_Dir/Subdir1/fo2'
mkdir: created directory `Main_Dir/Subdir1/f03'
mkdir: created directory `Main_Dir/Subdir2'
mkdir: created directory `Main_Dir/Subdir2/fo1'
mkdir: created directory `Main_Dir/Subdir2/fo2'
mkdir: created directory `Main_Dir/Subdir2/f03'
mkdir: created directory `Main_Dir/Subdir3'
mkdir: created directory `Main_Dir/Subdir3/fo1'
mkdir: created directory `Main_Dir/Subdir3/fo2'
mkdir: created directory `Main_Dir/Subdir3/f03'
gniourf@somewhere$ tree Main_Dir/
Main_Dir/
|-- Subdir1
|   |-- f03
|   |-- fo1
|   `-- fo2
|-- Subdir2
|   |-- f03
|   |-- fo1
|   `-- fo2
`-- Subdir3
    |-- f03
    |-- fo1
    `-- fo2

12 directories, 0 files
gniourf@somewhere$ mkdir Destination
gniourf@somewhere$ cp -nvr --parents -- Main_Dir/*/fo{1,2} Destination/
Main_Dir -> Destination/Main_Dir
Main_Dir/Subdir1 -> Destination/Main_Dir/Subdir1
`Main_Dir/Subdir1/fo1' -> `Destination/Main_Dir/Subdir1/fo1'
Main_Dir/Subdir2 -> Destination/Main_Dir/Subdir2
`Main_Dir/Subdir2/fo1' -> `Destination/Main_Dir/Subdir2/fo1'
Main_Dir/Subdir3 -> Destination/Main_Dir/Subdir3
`Main_Dir/Subdir3/fo1' -> `Destination/Main_Dir/Subdir3/fo1'
`Main_Dir/Subdir1/fo2' -> `Destination/Main_Dir/Subdir1/fo2'
`Main_Dir/Subdir2/fo2' -> `Destination/Main_Dir/Subdir2/fo2'
`Main_Dir/Subdir3/fo2' -> `Destination/Main_Dir/Subdir3/fo2'
gniourf@somewhere$ tree Destination
Destination
`-- Main_Dir
    |-- Subdir1
    |   |-- fo1
    |   `-- fo2
    |-- Subdir2
    |   |-- fo1
    |   `-- fo2
    `-- Subdir3
        |-- fo1
        `-- fo2

10 directories, 0 files
gniourf@somewhere$ # Done!

Make sure you use the --parent option with the -r switch. The -v option I used is so that the command is verbose (it shows what it's doing) and the -n option is for no clobber so as to not overwrite otherwise existing files (I use this one very often!).

If you don't want the Main_Dir to be in the directory, do it from within the Main_Dir directly:

gniourf@somewhere$ mkdir -p Main_Dir/Subdir{1..3}/f{o{1,2},03} Destination
gniourf@somewhere$ cd Main_Dir/
gniourf@somewhere$ cp -nvr --parents -- */fo{1,2} ../Destination
Subdir1 -> ../Destination/Subdir1
`Subdir1/fo1' -> `../Destination/Subdir1/fo1'
Subdir2 -> ../Destination/Subdir2
`Subdir2/fo1' -> `../Destination/Subdir2/fo1'
Subdir3 -> ../Destination/Subdir3
`Subdir3/fo1' -> `../Destination/Subdir3/fo1'
`Subdir1/fo2' -> `../Destination/Subdir1/fo2'
`Subdir2/fo2' -> `../Destination/Subdir2/fo2'
`Subdir3/fo2' -> `../Destination/Subdir3/fo2'
gniourf@somewhere$ cd ..
gniourf@somewhere$ tree Destination/
Destination/
|-- Subdir1
|   |-- fo1
|   `-- fo2
|-- Subdir2
|   |-- fo1
|   `-- fo2
`-- Subdir3
    |-- fo1
    `-- fo2

9 directories, 0 files
gniourf@somewhere$ 
4
  • And why is the best option? Nov 8, 2013 at 16:00
  • @RaduRădeanu Why isn't it the best? :) Nov 8, 2013 at 16:02
  • 1
    Well, is a good solution, nothing to say, but why you decided to be the best? In fact you have to use two commands to not copy Main_Dir to the destination. Honestly, I find rsync -av --exclude="f03" Main_Dir/ Destination more human readable and more applicable to the general case. Nov 8, 2013 at 16:15
  • @RaduRădeanu Maybe, but the rsync solution as you showed it, is not applicable to the general case either: if there are many folders to exclude, it's tedious and error prone to --exclude them all. Moreover, with the --exclude feature, you potentially exclude a f03 file that could be contained in a fo directory. Nov 8, 2013 at 17:50
-1

In your case it is just possible if the folders fo1, fo2, fo3 have different names, because you cannot have 3 folder with the same name in a folder. So if it looks like this:

user@host:~/test/1# find
.
./main
./main/sub1
./main/sub1/fo3
./main/sub1/fo1
./main/sub1/fo2
./main/sub2
./main/sub2/fo6
./main/sub2/fo4
./main/sub2/fo5
./main/sub3
./main/sub3/fo9
./main/sub3/fo8
./main/sub3/fo7

... you can copy (just the sub folders) by:

user@host:~/test/1# cp -R main/*/fo* ../2/

Now ../2/ looks like this:

user@host:~/test/1# cd ../2/
user@host:~/test/2# ls
fo1  fo2  fo3  fo4  fo5  fo6  fo7  fo8  fo9
4
  • 1
    Can you read better the question? The OP wants to copy Subdir1, Subdir2, Subdir3, but not fo3 from inside of them. Nov 8, 2013 at 7:59
  • Of course he wants: "But how would I only copy fo1 and fo2 folders to the new place?"
    – chaos
    Nov 8, 2013 at 8:00
  • 1
    Well, that's the question: only copy fo1 and fo2. This imply not fo3. Nov 8, 2013 at 8:03
  • The question is a bit confusing: In fact you can understand the question in 3 ways...
    – chaos
    Nov 8, 2013 at 8:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .