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 \;
John
  • 3,599

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
  • 42,678
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
  • 242,166
  • 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