If you only want to copy the directories and no files or sub-directories, it' easy:
terdon@oregano test folders $ tree
.
├── 1
│ ├── 1-1
│ ├── 1-2
│ ├── 1-3
│ ├── file-1
│ └── file-2
├── 2
│ ├── 2-1
│ ├── 2-2
│ ├── 2-3
│ ├── file-1
│ └── file-2
├── 3
│ ├── 3-1
│ ├── 3-2
│ ├── 3-3
│ ├── file-1
│ └── file-2
└── 4
├── 4-1
├── 4-2
├── 4-3
├── file-1
└── file-2
17 directories, 8 files
Using the above example, you can re-create the top level directories with:
terdon@oregano test folders $ find . -maxdepth 1 -type d -exec mkdir ../results/{} \;
mkdir: cannot create directory ‘../results/.’: File exists
$ tree ../results/
../results/
├── 1
├── 2
├── 3
└── 4
5 directories, 0 files
You can safely ignore the error message. That is just because it also finds .
, the current directory, and tries to create ../results/.
, that current directory, which already exists.
If you also want to copy the top-level files, you can do it in two steps:
terdon@oregano test folders $ find . -maxdepth 1 -type d -exec mkdir ../results/{} \;
mkdir: cannot create directory ‘../results/.’: File exists
$ find . -maxdepth 2 -type f -exec cp {} ../results/{} \;
Which produces:
$ tree ../results/
../results/
├── 1
│ ├── file-1
│ └── file-2
├── 2
│ ├── file-1
│ └── file-2
├── 3
│ ├── file-1
│ └── file-2
└── 4
├── file-1
└── file-2
You can also do it in a single pass with:
$ find . -maxdepth 1 -type d -exec sh -c 'mkdir ../results/$1 && cp {}/* ../results/$1' sh {} \;
mkdir: cannot create directory ‘../results/.’: File exists
cp: -r not specified; omitting directory './3/3-1'
cp: -r not specified; omitting directory './3/3-2'
cp: -r not specified; omitting directory './3/3-3'
cp: -r not specified; omitting directory './1/1-1'
cp: -r not specified; omitting directory './1/1-2'
cp: -r not specified; omitting directory './1/1-3'
cp: -r not specified; omitting directory './4/4-1'
cp: -r not specified; omitting directory './4/4-2'
cp: -r not specified; omitting directory './4/4-3'
cp: -r not specified; omitting directory './2/2-1'
cp: -r not specified; omitting directory './2/2-2'
cp: -r not specified; omitting directory './2/2-3'
Since we are using cp
without -r
, only files will be copied. You'll get those warnings, but again, you can safely ignore them. You can also silence them by redirecting to /dev/null
:
find . -maxdepth 1 -type d -exec sh -c 'mkdir ../results/$1 && cp {}/* ../results/$1' sh {} \; 2>/dev/null
cp
?rsync
usually handles those kind of sophisticated copy requirements much better. See rsync recursively with a certain depth of subfolders for example. – aviro Nov 22 '23 at 08:40-r
option, why not usecp --parents */* destination_directory
? – xhienne Nov 22 '23 at 10:42cp --parents */* dest
will copy the files among your parameters*/*
(if you want to copy more levels, then change the parameter:*/*/*
,*/*/*/*
, etc). The--parents
option will just recreate the directory hierarchy for those files in the destination directory. Just try it out! – xhienne Nov 22 '23 at 21:43