22

I have a directory-tree with a lot of files in it. I'd like to copy all of those files into one new directory, but with all files located in the base of the folder.

So I have something like this:

    images
    ├── avatar.png
    ├── bg.jpg
    ├── checkbox.png
    ├── cross.png
    ├── datatables
    │   ├── back_disabled.png
    │   ├── back_enabled.png
    │   ├── forward_disabled.png
    │   ├── forward_enabled.png
    │   ├── sort_asc.png
    │   ├── sort_asc_disabled.png
    │   ├── sort_both.png
    │   ├── sort_desc.png
    │   └── sort_desc_disabled.png
    ├── exclamation.png
    ├── forms
    │   ├── btn_left.gif
    │   ├── btn_right.gif
    │   ├── checkbox.gif
    │   ├── input
    │   │   ├── input_left-focus.gif
    │   │   ├── input_left-hover.gif
    │   │   ├── input_left.gif
    │   │   ├── input_right-focus.gif
    │   │   ├── input_right-hover.gif
    │   │   ├── input_right.gif
    │   │   ├── input_text_left.gif
    │   │   └── input_text_right.gif
    │   ├── radio.gif
    │   ├── select_left.gif
    │   ├── select_right.gif

And I'd like something like this:

    new_folder
    ├── avatar.png
    ├── bg.jpg
    ├── checkbox.png
    ├── cross.png
    ├── back_disabled.png
    ├── back_enabled.png
    ├── forward_disabled.png
    ├── forward_enabled.png
    ├── sort_asc.png
    ├── sort_asc_disabled.png
    ├── sort_both.png
    ├── sort_desc.png
    ├── sort_desc_disabled.png
    ├── exclamation.png
    ├── btn_left.gif
    ├── btn_right.gif
    ├── checkbox.gif
    ├── input_left-focus.gif
    ├── input_left-hover.gif
    ├── input_left.gif
    ├── input_right-focus.gif
    ├── input_right-hover.gif
    ├── input_right.gif
    ├── input_text_left.gif
    ├── input_text_right.gif
    ├── radio.gif
    ├── select_left.gif
    ├── select_right.gif

I'm pretty sure there is a bashcommand for that, but I haven't found it yet. Do you have any ideas?

CS

john-jones
  • 7,490
  • 18
  • 53
  • 86
csch
  • 4,496
  • 2
  • 19
  • 23

4 Answers4

35
find /source-tree -type f -exec cp {} /target-dir \;
Kaz
  • 55,781
  • 9
  • 100
  • 149
  • this is truely the best solution. Is it possible that you breakdown the command and explain what which "operator" does? f.e -type? Would be very cool tho! – y.y Oct 02 '20 at 11:09
13

you are looking for ways to flatten the directory

find /images -iname '*.jpg' -exec cp --target-directory /newfolder/ {} \;

find all files iname in case insensitive name mode.
cp copy once to --target-directory named /newfolder/.
{} expand the list from find into the form of /dir/file.jpg /dir/dir2/bla.jpg.

cctan
  • 2,015
  • 3
  • 19
  • 29
  • 2
    didn't work for me with "cp: illegal option -- -". Kaz's answer worked for me – alexey Mar 07 '16 at 22:04
  • @alexey I cant reproduce your error, what environment did you run it in? – cctan Mar 08 '16 at 02:11
  • oh you're right - I'm using OSX's (10.11.2) built in bash which is known to be out of date: GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15) – alexey Mar 09 '16 at 18:09
  • It doesn't work on alpine based docker also, am getting the following `cp: unrecognized option: target-directory` `BusyBox v1.28.4 (2018-07-17 15:21:40 UTC) multi-call binary.` – julianalimin Nov 03 '18 at 14:56
2

On zsh:

cp /source/**/* /destination

gbin
  • 2,960
  • 1
  • 14
  • 11
0
$ cd images && cp ** new_folder/
Grégory Roche
  • 162
  • 2
  • 9