6

So I was looking around and all I have found is how to do this only if the directory is already made, which is this:

find source -name '*.z' -exec cp {} destination \;

But how can I make a new directory where I want to send these files in the same command? This is what I have tried but with no success:

find source -name '*.z' -exec cp {} | mkdir newDirectory \;
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
John
  • 3,459
  • 13
  • 29
  • 25

2 Answers2

11

One option is to use the install command instead of cp. It has an option to create all of the leading directories.

find source -name '*.z' -exec install -D {} dest \;
jordanm
  • 41,988
  • 9
  • 116
  • 113
1

You can't pipe data to mkdir that way. You could do something like this:

find source -name '*.z' -exec sh -c 'mkdir -p newDirectory && cp "$@" newDirectory' _ {} +

or (assuming file names not containing newlines)

find source -name '*.z' | while IFS= read -r foo; do 
   mkdir -p newDirectory;
   cp "$foo" newDirectory;
done 

or if you only want to create one directory, so the name is always the same:

mkdir newDirectory; find source -name '*.z' -exec cp {} newDirectory \;
terdon
  • 234,489
  • 66
  • 447
  • 667
  • Does find actually change the working directory as it goes? Won't this try making a directory in the same place each time and copy all the files into it? If he wanted them all in one directory, I can't see why he'd need to create the directory as he worked... – kurtm Oct 12 '13 at 15:56
  • Is there any way to do the first way without a bash statement? Possibly piped? – John Oct 12 '13 at 15:56
  • @kurtm see updated answer, and yes, apparently `find` changes the CWD as it goes, it will create the directory in the same place. – terdon Oct 12 '13 at 15:58
  • @John see updated answer. You cannot pipe data to `mkdir`. – terdon Oct 12 '13 at 15:58
  • @terdon Okay. I wasn't sure since it give relatives paths for output. – kurtm Oct 12 '13 at 15:59
  • @kurtm it was a good point, neither was I. Had to test to check. – terdon Oct 12 '13 at 16:00
  • @terdon So find puts something different in place of {} than it does when it does `-print`? – kurtm Oct 12 '13 at 16:11
  • @kurtm really don't know. I remember there was a question on the site about this. In ay case, I tested and when the `.z` file was in a subdirectory, `find` still copied to the `newDir` in the parent so it seems to deal somehow. My guess is that since it uses the full path, it won't cd into the directory a file was found in when executing `-exec` calls. If you want more details that that, try pinging one of the heavyweights in chat :). – terdon Oct 12 '13 at 16:13
  • @kurtm `find` does not change the working directory (except with `-execdir`, which does exactly that). A pipe would be a bash statement — why don't you want to do this the straightforward way? – Gilles 'SO- stop being evil' Oct 12 '13 at 23:54
  • @Gilles You asking me or OP? I like straightforward, I was just asking terdon about his proposed solution. – kurtm Oct 13 '13 at 05:51